f92bc6cba8b50245b41054127a5a2bb9220112e7
[pspp] / tests / libpspp / ll-test.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2006, 2010 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
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.
22
23    This test program depends only on ll.c and the standard C
24    library.
25
26    See llx-test.c for a similar program for the llx_*
27    routines. */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include <libpspp/ll.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 \f
38 /* Support preliminaries. */
39 #if __GNUC__ >= 2 && !defined UNUSED
40 #define UNUSED __attribute__ ((unused))
41 #else
42 #define UNUSED
43 #endif
44
45 /* Exit with a failure code.
46    (Place a breakpoint on this function while debugging.) */
47 static void
48 check_die (void)
49 {
50   exit (EXIT_FAILURE);
51 }
52
53 /* If OK is not true, prints a message about failure on the
54    current source file and the given LINE and terminates. */
55 static void
56 check_func (bool ok, int line)
57 {
58   if (!ok)
59     {
60       fprintf (stderr, "%s:%d: check failed\n", __FILE__, line);
61       check_die ();
62     }
63 }
64
65 /* Verifies that EXPR evaluates to true.
66    If not, prints a message citing the calling line number and
67    terminates. */
68 #define check(EXPR) check_func ((EXPR), __LINE__)
69
70 /* Prints a message about memory exhaustion and exits with a
71    failure code. */
72 static void
73 xalloc_die (void)
74 {
75   printf ("virtual memory exhausted\n");
76   exit (EXIT_FAILURE);
77 }
78
79 /* Allocates and returns N bytes of memory. */
80 static void *
81 xmalloc (size_t n)
82 {
83   if (n != 0)
84     {
85       void *p = malloc (n);
86       if (p == NULL)
87         xalloc_die ();
88
89       return p;
90     }
91   else
92     return NULL;
93 }
94
95 /* Allocates and returns N * M bytes of memory. */
96 static void *
97 xnmalloc (size_t n, size_t m)
98 {
99   if ((size_t) -1 / m <= n)
100     xalloc_die ();
101   return xmalloc (n * m);
102 }
103 \f
104 /* List type and support routines. */
105
106 /* Test data element. */
107 struct element
108   {
109     struct ll ll;               /* Embedded list element. */
110     int x;                      /* Primary value. */
111     int y;                      /* Secondary value. */
112   };
113
114 static int aux_data;
115
116 /* Returns the `struct element' that LL is embedded within. */
117 static struct element *
118 ll_to_element (const struct ll *ll)
119 {
120   return ll_data (ll, struct element, ll);
121 }
122
123 /* Prints the elements in LIST. */
124 static void UNUSED
125 print_list (struct ll_list *list)
126 {
127   struct ll *x;
128
129   printf ("list:");
130   for (x = ll_head (list); x != ll_null (list); x = ll_next (x))
131     {
132       struct element *e = ll_to_element (x);
133       printf (" %d", e->x);
134     }
135   printf ("\n");
136 }
137
138 /* Prints the value returned by PREDICATE given auxiliary data
139    AUX for each element in LIST. */
140 static void UNUSED
141 print_pred (struct ll_list *list,
142             ll_predicate_func *predicate, void *aux UNUSED)
143 {
144   struct ll *x;
145
146   printf ("pred:");
147   for (x = ll_head (list); x != ll_null (list); x = ll_next (x))
148     printf (" %d", predicate (x, aux));
149   printf ("\n");
150 }
151
152 /* Prints the CNT numbers in VALUES. */
153 static void UNUSED
154 print_array (int values[], size_t cnt)
155 {
156   size_t i;
157
158   printf ("arry:");
159   for (i = 0; i < cnt; i++)
160     printf (" %d", values[i]);
161   printf ("\n");
162 }
163
164 /* Compares the `x' values in A and B and returns a strcmp-type
165    return value.  Verifies that AUX points to aux_data. */
166 static int
167 compare_elements (const struct ll *a_, const struct ll *b_, void *aux)
168 {
169   const struct element *a = ll_to_element (a_);
170   const struct element *b = ll_to_element (b_);
171
172   check (aux == &aux_data);
173   return a->x < b->x ? -1 : a->x > b->x;
174 }
175
176 /* Compares the `x' and `y' values in A and B and returns a
177    strcmp-type return value.  Verifies that AUX points to
178    aux_data. */
179 static int
180 compare_elements_x_y (const struct ll *a_, const struct ll *b_, void *aux)
181 {
182   const struct element *a = ll_to_element (a_);
183   const struct element *b = ll_to_element (b_);
184
185   check (aux == &aux_data);
186   if (a->x != b->x)
187     return a->x < b->x ? -1 : 1;
188   else if (a->y != b->y)
189     return a->y < b->y ? -1 : 1;
190   else
191     return 0;
192 }
193
194 /* Compares the `y' values in A and B and returns a strcmp-type
195    return value.  Verifies that AUX points to aux_data. */
196 static int
197 compare_elements_y (const struct ll *a_, const struct ll *b_, void *aux)
198 {
199   const struct element *a = ll_to_element (a_);
200   const struct element *b = ll_to_element (b_);
201
202   check (aux == &aux_data);
203   return a->y < b->y ? -1 : a->y > b->y;
204 }
205
206 /* Returns true if the bit in *PATTERN indicated by `x in
207    *ELEMENT is set, false otherwise. */
208 static bool
209 pattern_pred (const struct ll *element_, void *pattern_)
210 {
211   const struct element *element = ll_to_element (element_);
212   unsigned int *pattern = pattern_;
213
214   return (*pattern & (1u << element->x)) != 0;
215 }
216
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
221    nonnull.
222    Allocates space for N values in *VALUES, if VALUES is
223    nonnull. */
224 static void
225 allocate_elements (size_t n,
226                    struct ll_list *list,
227                    struct element ***elems,
228                    struct ll ***elemp,
229                    int **values)
230 {
231   size_t i;
232
233   if (list != NULL)
234     ll_init (list);
235
236   *elems = xnmalloc (n, sizeof **elems);
237   for (i = 0; i < n; i++)
238     {
239       (*elems)[i] = xmalloc (sizeof ***elems);
240       if (list != NULL)
241         ll_push_tail (list, &(*elems)[i]->ll);
242     }
243
244   if (elemp != NULL)
245     {
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);
250     }
251
252   if (values != NULL)
253     *values = xnmalloc (n, sizeof *values);
254 }
255
256 /* Copies the CNT values of `x' from LIST into VALUES[]. */
257 static void
258 extract_values (struct ll_list *list, int values[], size_t cnt)
259 {
260   struct ll *x;
261
262   check (ll_count (list) == cnt);
263   for (x = ll_head (list); x != ll_null (list); x = ll_next (x))
264     {
265       struct element *e = ll_to_element (x);
266       *values++ = e->x;
267     }
268 }
269
270 /* As allocate_elements, but sets ascending values, starting
271    from 0, in `x' values in *ELEMS and in *VALUES (if
272    nonnull). */
273 static void
274 allocate_ascending (size_t n,
275                     struct ll_list *list,
276                     struct element ***elems,
277                     struct ll ***elemp,
278                     int **values)
279 {
280   size_t i;
281
282   allocate_elements (n, list, elems, elemp, values);
283
284   for (i = 0; i < n; i++)
285     (*elems)[i]->x = i;
286   if (values != NULL)
287     extract_values (list, *values, n);
288 }
289
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). */
293 static void
294 allocate_pattern (size_t n,
295                   int pattern,
296                   struct ll_list *list,
297                   struct element ***elems,
298                   struct ll ***elemp,
299                   int **values)
300 {
301   size_t i;
302
303   allocate_elements (n, list, elems, elemp, values);
304
305   for (i = 0; i < n; i++)
306     (*elems)[i]->x = (pattern & (1 << i)) != 0;
307   if (values != NULL)
308     extract_values (list, *values, n);
309 }
310
311 /* Randomly shuffles the CNT elements in ARRAY, each of which is
312    SIZE bytes in size. */
313 static void
314 random_shuffle (void *array_, size_t cnt, size_t size)
315 {
316   char *array = array_;
317   char *tmp = xmalloc (size);
318   size_t i;
319
320   for (i = 0; i < cnt; i++)
321     {
322       size_t j = rand () % (cnt - i) + i;
323       if (i != j)
324         {
325           memcpy (tmp, array + j * size, size);
326           memcpy (array + j * size, array + i * size, size);
327           memcpy (array + i * size, tmp, size);
328         }
329     }
330
331   free (tmp);
332 }
333
334 /* As allocate_ascending, but orders the values randomly. */
335 static void
336 allocate_random (size_t n,
337                  struct ll_list *list,
338                  struct element ***elems,
339                  struct ll ***elemp,
340                  int **values)
341 {
342   size_t i;
343
344   allocate_elements (n, list, elems, elemp, values);
345
346   for (i = 0; i < n; i++)
347     (*elems)[i]->x = i;
348   random_shuffle (*elems, n, sizeof **elems);
349   if (values != NULL)
350     extract_values (list, *values, n);
351 }
352
353 /* Frees the N elements of ELEMS, ELEMP, and VALUES. */
354 static void
355 free_elements (size_t n,
356                struct element **elems,
357                struct ll **elemp,
358                int *values)
359 {
360   size_t i;
361
362   for (i = 0; i < n; i++)
363     free (elems[i]);
364   free (elems);
365   free (elemp);
366   free (values);
367 }
368
369 /* Compares A and B and returns a strcmp-type return value. */
370 static int
371 compare_ints (const void *a_, const void *b_, void *aux UNUSED)
372 {
373   const int *a = a_;
374   const int *b = b_;
375
376   return *a < *b ? -1 : *a > *b;
377 }
378
379 /* Compares A and B and returns a strcmp-type return value. */
380 static int
381 compare_ints_noaux (const void *a_, const void *b_)
382 {
383   const int *a = a_;
384   const int *b = b_;
385
386   return *a < *b ? -1 : *a > *b;
387 }
388
389 /* Checks that LIST contains the CNT values in ELEMENTS. */
390 static void
391 check_list_contents (struct ll_list *list, int elements[], size_t cnt)
392 {
393   struct ll *ll;
394   size_t i;
395
396   check ((cnt == 0) == ll_is_empty (list));
397
398   /* Iterate in forward order. */
399   for (ll = ll_head (list), i = 0; i < cnt; ll = ll_next (ll), i++)
400     {
401       struct element *e = ll_to_element (ll);
402       check (elements[i] == e->x);
403       check (ll != ll_null (list));
404     }
405   check (ll == ll_null (list));
406
407   /* Iterate in reverse order. */
408   for (ll = ll_tail (list), i = 0; i < cnt; ll = ll_prev (ll), i++)
409     {
410       struct element *e = ll_to_element (ll);
411       check (elements[cnt - i - 1] == e->x);
412       check (ll != ll_null (list));
413     }
414   check (ll == ll_null (list));
415
416   check (ll_count (list) == cnt);
417 }
418
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
423    data. */
424 static int
425 lexicographical_compare_3way (const void *array1, size_t count1,
426                               const void *array2, size_t count2,
427                               size_t size,
428                               int (*compare) (const void *, const void *,
429                                               void *aux),
430                               void *aux)
431 {
432   const char *first1 = array1;
433   const char *first2 = array2;
434   size_t min_count = count1 < count2 ? count1 : count2;
435
436   while (min_count > 0)
437     {
438       int cmp = compare (first1, first2, aux);
439       if (cmp != 0)
440         return cmp;
441
442       first1 += size;
443       first2 += size;
444       min_count--;
445     }
446
447   return count1 < count2 ? -1 : count1 > count2;
448 }
449 \f
450 /* Tests. */
451
452 /* Tests list push and pop operations. */
453 static void
454 test_push_pop (void)
455 {
456   const int max_elems = 1024;
457
458   struct ll_list list;
459   struct element **elems;
460   int *values;
461
462   int i;
463
464   allocate_elements (max_elems, NULL, &elems, NULL, &values);
465
466   /* Push on tail. */
467   ll_init (&list);
468   check_list_contents (&list, NULL, 0);
469   for (i = 0; i < max_elems; i++)
470     {
471       values[i] = elems[i]->x = i;
472       ll_push_tail (&list, &elems[i]->ll);
473       check_list_contents (&list, values, i + 1);
474     }
475
476   /* Remove from tail. */
477   for (i = 0; i < max_elems; i++)
478     {
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);
482     }
483
484   /* Push at start. */
485   check_list_contents (&list, NULL, 0);
486   for (i = 0; i < max_elems; i++)
487     {
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);
491     }
492
493   /* Remove from start. */
494   for (i = 0; i < max_elems; i++)
495     {
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);
499     }
500
501   free_elements (max_elems, elems, NULL, values);
502 }
503
504 /* Tests insertion and removal at arbitrary positions. */
505 static void
506 test_insert_remove (void)
507 {
508   const int max_elems = 16;
509   int cnt;
510
511   for (cnt = 0; cnt < max_elems; cnt++)
512     {
513       struct element **elems;
514       struct ll **elemp;
515       int *values = xnmalloc (cnt + 1, sizeof *values);
516
517       struct ll_list list;
518       struct element extra;
519       int pos;
520
521       allocate_ascending (cnt, &list, &elems, &elemp, NULL);
522       extra.x = -1;
523       for (pos = 0; pos <= cnt; pos++)
524         {
525           int i, j;
526
527           ll_insert (elemp[pos], &extra.ll);
528
529           j = 0;
530           for (i = 0; i < pos; i++)
531             values[j++] = i;
532           values[j++] = -1;
533           for (; i < cnt; i++)
534             values[j++] = i;
535           check_list_contents (&list, values, cnt + 1);
536
537           ll_remove (&extra.ll);
538         }
539       check_list_contents (&list, values, cnt);
540
541       free_elements (cnt, elems, elemp, values);
542     }
543 }
544
545 /* Tests swapping individual elements. */
546 static void
547 test_swap (void)
548 {
549   const int max_elems = 8;
550   int cnt;
551
552   for (cnt = 0; cnt <= max_elems; cnt++)
553     {
554       struct ll_list list;
555       struct element **elems;
556       int *values;
557
558       int i, j, k;
559
560       allocate_ascending (cnt, &list, &elems, NULL, &values);
561       check_list_contents (&list, values, cnt);
562
563       for (i = 0; i < cnt; i++)
564         for (j = 0; j < cnt; j++)
565           for (k = 0; k < 2; k++)
566             {
567               int t;
568
569               ll_swap (&elems[i]->ll, &elems[j]->ll);
570               t = values[i];
571               values[i] = values[j];
572               values[j] = t;
573               check_list_contents (&list, values, cnt);
574             }
575
576       free_elements (cnt, elems, NULL, values);
577     }
578 }
579
580 /* Tests swapping ranges of list elements. */
581 static void
582 test_swap_range (void)
583 {
584   const int max_elems = 8;
585   int cnt, a0, a1, b0, b1, r;
586
587   for (cnt = 0; cnt <= max_elems; cnt++)
588     for (a0 = 0; a0 <= cnt; a0++)
589       for (a1 = a0; a1 <= cnt; a1++)
590         for (b0 = a1; b0 <= cnt; b0++)
591           for (b1 = b0; b1 <= cnt; b1++)
592             for (r = 0; r < 2; r++)
593               {
594                 struct ll_list list;
595                 struct element **elems;
596                 struct ll **elemp;
597                 int *values;
598
599                 int i, j;
600
601                 allocate_ascending (cnt, &list, &elems, &elemp, &values);
602                 check_list_contents (&list, values, cnt);
603
604                 j = 0;
605                 for (i = 0; i < a0; i++)
606                   values[j++] = i;
607                 for (i = b0; i < b1; i++)
608                   values[j++] = i;
609                 for (i = a1; i < b0; i++)
610                   values[j++] = i;
611                 for (i = a0; i < a1; i++)
612                   values[j++] = i;
613                 for (i = b1; i < cnt; i++)
614                   values[j++] = i;
615                 check (j == cnt);
616
617                 if (r == 0)
618                   ll_swap_range (elemp[a0], elemp[a1], elemp[b0], elemp[b1]);
619                 else
620                   ll_swap_range (elemp[b0], elemp[b1], elemp[a0], elemp[a1]);
621                 check_list_contents (&list, values, cnt);
622
623                 free_elements (cnt, elems, elemp, values);
624               }
625 }
626
627 /* Tests removing ranges of list elements. */
628 static void
629 test_remove_range (void)
630 {
631   const int max_elems = 8;
632
633   int cnt, r0, r1;
634
635   for (cnt = 0; cnt <= max_elems; cnt++)
636     for (r0 = 0; r0 <= cnt; r0++)
637       for (r1 = r0; r1 <= cnt; r1++)
638         {
639           struct ll_list list;
640           struct element **elems;
641           struct ll **elemp;
642           int *values;
643
644           int i, j;
645
646           allocate_ascending (cnt, &list, &elems, &elemp, &values);
647           check_list_contents (&list, values, cnt);
648
649           j = 0;
650           for (i = 0; i < r0; i++)
651             values[j++] = i;
652           for (i = r1; i < cnt; i++)
653             values[j++] = i;
654
655           ll_remove_range (elemp[r0], elemp[r1]);
656           check_list_contents (&list, values, j);
657
658           free_elements (cnt, elems, elemp, values);
659         }
660 }
661
662 /* Tests ll_remove_equal. */
663 static void
664 test_remove_equal (void)
665 {
666   const int max_elems = 8;
667
668   int cnt, r0, r1, eq_pat;
669
670   for (cnt = 0; cnt <= max_elems; cnt++)
671     for (r0 = 0; r0 <= cnt; r0++)
672       for (r1 = r0; r1 <= cnt; r1++)
673         for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
674           {
675             struct ll_list list;
676             struct element **elems;
677             struct ll **elemp;
678             int *values;
679
680             struct element to_remove;
681             int remaining;
682             int i;
683
684             allocate_elements (cnt, &list, &elems, &elemp, &values);
685
686             remaining = 0;
687             for (i = 0; i < cnt; i++)
688               {
689                 int x = eq_pat & (1 << i) ? -1 : i;
690                 bool delete = x == -1 && r0 <= i && i < r1;
691                 elems[i]->x = x;
692                 if (!delete)
693                   values[remaining++] = x;
694               }
695
696             to_remove.x = -1;
697             check ((int) ll_remove_equal (elemp[r0], elemp[r1], &to_remove.ll,
698                                           compare_elements, &aux_data)
699                    == cnt - remaining);
700             check_list_contents (&list, values, remaining);
701
702             free_elements (cnt, elems, elemp, values);
703           }
704 }
705
706 /* Tests ll_remove_if. */
707 static void
708 test_remove_if (void)
709 {
710   const int max_elems = 8;
711
712   int cnt, r0, r1, pattern;
713
714   for (cnt = 0; cnt <= max_elems; cnt++)
715     for (r0 = 0; r0 <= cnt; r0++)
716       for (r1 = r0; r1 <= cnt; r1++)
717         for (pattern = 0; pattern <= 1 << cnt; pattern++)
718           {
719             struct ll_list list;
720             struct element **elems;
721             struct ll **elemp;
722             int *values;
723
724             int remaining;
725             int i;
726
727             allocate_elements (cnt, &list, &elems, &elemp, &values);
728
729             remaining = 0;
730             for (i = 0; i < cnt; i++)
731               {
732                 bool delete = (pattern & (1 << i)) && r0 <= i && i < r1;
733                 elems[i]->x = i;
734                 if (!delete)
735                   values[remaining++] = i;
736               }
737
738             check ((int) ll_remove_if (elemp[r0], elemp[r1],
739                                        pattern_pred, &pattern)
740                    == cnt - remaining);
741             check_list_contents (&list, values, remaining);
742
743             free_elements (cnt, elems, elemp, values);
744           }
745 }
746
747 /* Tests ll_moved. */
748 static void
749 test_moved (void)
750 {
751   const int max_elems = 8;
752
753   int cnt;
754
755   for (cnt = 0; cnt <= max_elems; cnt++)
756     {
757       struct ll_list list;
758       struct element **elems;
759       struct element **new_elems;
760       int *values;
761
762       int i;
763
764       allocate_ascending (cnt, &list, &elems, NULL, &values);
765       allocate_elements (cnt, NULL, &new_elems, NULL, NULL);
766       check_list_contents (&list, values, cnt);
767
768       for (i = 0; i < cnt; i++)
769         {
770           *new_elems[i] = *elems[i];
771           ll_moved (&new_elems[i]->ll);
772           check_list_contents (&list, values, cnt);
773         }
774
775       free_elements (cnt, elems, NULL, values);
776       free_elements (cnt, new_elems, NULL, NULL);
777     }
778 }
779
780 /* Tests, via HELPER, a function that looks at list elements
781    equal to some specified element. */
782 static void
783 test_examine_equal_range (void (*helper) (int r0, int r1, int eq_pat,
784                                           struct ll *to_find,
785                                           struct ll **elemp))
786 {
787   const int max_elems = 8;
788
789   int cnt, r0, r1, eq_pat;
790
791   for (cnt = 0; cnt <= max_elems; cnt++)
792     for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
793       {
794         struct ll_list list;
795         struct element **elems;
796         struct ll **elemp;
797         int *values;
798
799         struct element to_find;
800
801         int i;
802
803         allocate_ascending (cnt, &list, &elems, &elemp, &values);
804
805         for (i = 0; i < cnt; i++)
806           if (eq_pat & (1 << i))
807             values[i] = elems[i]->x = -1;
808
809         to_find.x = -1;
810         for (r0 = 0; r0 <= cnt; r0++)
811           for (r1 = r0; r1 <= cnt; r1++)
812             helper (r0, r1, eq_pat, &to_find.ll, elemp);
813
814         check_list_contents (&list, values, cnt);
815
816         free_elements (cnt, elems, elemp, values);
817       }
818 }
819
820 /* Tests, via HELPER, a function that looks at list elements for
821    which a given predicate returns true. */
822 static void
823 test_examine_if_range (void (*helper) (int r0, int r1, int eq_pat,
824                                        struct ll **elemp))
825 {
826   const int max_elems = 8;
827
828   int cnt, r0, r1, eq_pat;
829
830   for (cnt = 0; cnt <= max_elems; cnt++)
831     for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
832       {
833         struct ll_list list;
834         struct element **elems;
835         struct ll **elemp;
836         int *values;
837
838         allocate_ascending (cnt, &list, &elems, &elemp, &values);
839
840         for (r0 = 0; r0 <= cnt; r0++)
841           for (r1 = r0; r1 <= cnt; r1++)
842             helper (r0, r1, eq_pat, elemp);
843
844         check_list_contents (&list, values, cnt);
845
846         free_elements (cnt, elems, elemp, values);
847       }
848 }
849
850 /* Helper function for testing ll_find_equal. */
851 static void
852 test_find_equal_helper (int r0, int r1, int eq_pat,
853                         struct ll *to_find, struct ll **elemp)
854 {
855   struct ll *match;
856   int i;
857
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))
862       break;
863
864   check (match == elemp[i]);
865 }
866
867 /* Tests ll_find_equal. */
868 static void
869 test_find_equal (void)
870 {
871   test_examine_equal_range (test_find_equal_helper);
872 }
873
874 /* Helper function for testing ll_find_if. */
875 static void
876 test_find_if_helper (int r0, int r1, int eq_pat, struct ll **elemp)
877 {
878   struct ll *match = ll_find_if (elemp[r0], elemp[r1],
879                                  pattern_pred, &eq_pat);
880   int i;
881
882   for (i = r0; i < r1; i++)
883     if (eq_pat & (1 << i))
884       break;
885
886   check (match == elemp[i]);
887 }
888
889 /* Tests ll_find_if. */
890 static void
891 test_find_if (void)
892 {
893   test_examine_if_range (test_find_if_helper);
894 }
895
896 /* Tests ll_find_adjacent_equal. */
897 static void
898 test_find_adjacent_equal (void)
899 {
900   const int max_elems = 8;
901
902   int cnt, eq_pat;
903
904   for (cnt = 0; cnt <= max_elems; cnt++)
905     for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
906       {
907         struct ll_list list;
908         struct element **elems;
909         struct ll **elemp;
910         int *values;
911         int match;
912
913         int i;
914
915         allocate_ascending (cnt, &list, &elems, &elemp, &values);
916
917         match = -1;
918         for (i = 0; i < cnt - 1; i++)
919           {
920             elems[i]->y = i;
921             if (eq_pat & (1 << i))
922               {
923                 values[i] = elems[i]->x = match;
924                 values[i + 1] = elems[i + 1]->x = match;
925               }
926             else
927               match--;
928           }
929
930         for (i = 0; i <= cnt; i++)
931           {
932             struct ll *ll1 = ll_find_adjacent_equal (elemp[i], ll_null (&list),
933                                                      compare_elements,
934                                                      &aux_data);
935             struct ll *ll2;
936             int j;
937
938             ll2 = ll_null (&list);
939             for (j = i; j < cnt - 1; j++)
940               if (eq_pat & (1 << j))
941                 {
942                   ll2 = elemp[j];
943                   break;
944                 }
945             check (ll1 == ll2);
946           }
947         check_list_contents (&list, values, cnt);
948
949         free_elements (cnt, elems, elemp, values);
950       }
951 }
952
953 /* Helper function for testing ll_count_range. */
954 static void
955 test_count_range_helper (int r0, int r1, int eq_pat UNUSED, struct ll **elemp)
956 {
957   check ((int) ll_count_range (elemp[r0], elemp[r1]) == r1 - r0);
958 }
959
960 /* Tests ll_count_range. */
961 static void
962 test_count_range (void)
963 {
964   test_examine_if_range (test_count_range_helper);
965 }
966
967 /* Helper function for testing ll_count_equal. */
968 static void
969 test_count_equal_helper (int r0, int r1, int eq_pat,
970                          struct ll *to_find, struct ll **elemp)
971 {
972   int count1, count2;
973   int i;
974
975   count1 = ll_count_equal (elemp[r0], elemp[r1], to_find,
976                            compare_elements, &aux_data);
977   count2 = 0;
978   for (i = r0; i < r1; i++)
979     if (eq_pat & (1 << i))
980       count2++;
981
982   check (count1 == count2);
983 }
984
985 /* Tests ll_count_equal. */
986 static void
987 test_count_equal (void)
988 {
989   test_examine_equal_range (test_count_equal_helper);
990 }
991
992 /* Helper function for testing ll_count_if. */
993 static void
994 test_count_if_helper (int r0, int r1, int eq_pat, struct ll **elemp)
995 {
996   int count1;
997   int count2;
998   int i;
999
1000   count1 = ll_count_if (elemp[r0], elemp[r1], pattern_pred, &eq_pat);
1001
1002   count2 = 0;
1003   for (i = r0; i < r1; i++)
1004     if (eq_pat & (1 << i))
1005       count2++;
1006
1007   check (count1 == count2);
1008 }
1009
1010 /* Tests ll_count_if. */
1011 static void
1012 test_count_if (void)
1013 {
1014   test_examine_if_range (test_count_if_helper);
1015 }
1016
1017 /* Returns N!. */
1018 static unsigned int
1019 factorial (unsigned int n)
1020 {
1021   unsigned int value = 1;
1022   while (n > 1)
1023     value *= n--;
1024   return value;
1025 }
1026
1027 /* Returns the number of permutations of the CNT values in
1028    VALUES.  If VALUES contains duplicates, they must be
1029    adjacent. */
1030 static unsigned int
1031 expected_perms (int *values, size_t cnt)
1032 {
1033   size_t i, j;
1034   unsigned int perm_cnt;
1035
1036   perm_cnt = factorial (cnt);
1037   for (i = 0; i < cnt; i = j)
1038     {
1039       for (j = i + 1; j < cnt; j++)
1040         if (values[i] != values[j])
1041           break;
1042       perm_cnt /= factorial (j - i);
1043     }
1044   return perm_cnt;
1045 }
1046
1047 /* Tests ll_min and ll_max. */
1048 static void
1049 test_min_max (void)
1050 {
1051   const int max_elems = 6;
1052   int cnt;
1053
1054   for (cnt = 0; cnt <= max_elems; cnt++)
1055     {
1056       struct ll_list list;
1057       struct element **elems;
1058       struct ll **elemp;
1059       int *values;
1060       int *new_values = xnmalloc (cnt, sizeof *values);
1061
1062       size_t perm_cnt;
1063
1064       allocate_ascending (cnt, &list, &elems, &elemp, &values);
1065
1066       perm_cnt = 1;
1067       while (ll_next_permutation (ll_head (&list), ll_null (&list),
1068                                   compare_elements, &aux_data))
1069         {
1070           int r0, r1;
1071           struct ll *x;
1072           int i;
1073
1074           for (i = 0, x = ll_head (&list); x != ll_null (&list);
1075                x = ll_next (x), i++)
1076             {
1077               struct element *e = ll_to_element (x);
1078               elemp[i] = x;
1079               new_values[i] = e->x;
1080             }
1081           for (r0 = 0; r0 <= cnt; r0++)
1082             for (r1 = r0; r1 <= cnt; r1++)
1083               {
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);
1088                 if (r0 == r1)
1089                   {
1090                     check (min == elemp[r1]);
1091                     check (max == elemp[r1]);
1092                   }
1093                 else
1094                   {
1095                     int min_int, max_int;
1096                     int i;
1097
1098                     min_int = max_int = new_values[r0];
1099                     for (i = r0; i < r1; i++)
1100                       {
1101                         int value = new_values[i];
1102                         if (value < min_int)
1103                           min_int = value;
1104                         if (value > max_int)
1105                           max_int = value;
1106                       }
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);
1111                   }
1112               }
1113           perm_cnt++;
1114         }
1115       check (perm_cnt == factorial (cnt));
1116       check_list_contents (&list, values, cnt);
1117
1118       free_elements (cnt, elems, elemp, values);
1119       free (new_values);
1120     }
1121 }
1122
1123 /* Tests ll_lexicographical_compare_3way. */
1124 static void
1125 test_lexicographical_compare_3way (void)
1126 {
1127   const int max_elems = 4;
1128
1129   int cnt_a, pat_a, cnt_b, pat_b;
1130
1131   for (cnt_a = 0; cnt_a <= max_elems; cnt_a++)
1132     for (pat_a = 0; pat_a <= 1 << cnt_a; pat_a++)
1133       for (cnt_b = 0; cnt_b <= max_elems; cnt_b++)
1134         for (pat_b = 0; pat_b <= 1 << cnt_b; pat_b++)
1135           {
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;
1140
1141             int a0, a1, b0, b1;
1142
1143             allocate_pattern (cnt_a, pat_a,
1144                               &list_a, &elems_a, &elemp_a, &values_a);
1145             allocate_pattern (cnt_b, pat_b,
1146                               &list_b, &elems_b, &elemp_b, &values_b);
1147
1148             for (a0 = 0; a0 <= cnt_a; a0++)
1149               for (a1 = a0; a1 <= cnt_a; a1++)
1150                 for (b0 = 0; b0 <= cnt_b; b0++)
1151                   for (b1 = b0; b1 <= cnt_b; b1++)
1152                     {
1153                       int a_ordering = lexicographical_compare_3way (
1154                         values_a + a0, a1 - a0,
1155                         values_b + b0, b1 - b0,
1156                         sizeof *values_a,
1157                         compare_ints, NULL);
1158
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);
1163
1164                       check (a_ordering == b_ordering);
1165                     }
1166
1167             free_elements (cnt_a, elems_a, elemp_a, values_a);
1168             free_elements (cnt_b, elems_b, elemp_b, values_b);
1169           }
1170 }
1171
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. */
1174 static void
1175 apply_func (struct ll *e_, void *next_output_)
1176 {
1177   struct element *e = ll_to_element (e_);
1178   int **next_output = next_output_;
1179
1180   *(*next_output)++ = e->x;
1181 }
1182
1183 /* Tests ll_apply. */
1184 static void
1185 test_apply (void)
1186 {
1187   const int max_elems = 8;
1188
1189   int cnt, r0, r1;
1190
1191   for (cnt = 0; cnt <= max_elems; cnt++)
1192     for (r0 = 0; r0 <= cnt; r0++)
1193       for (r1 = r0; r1 <= cnt; r1++)
1194         {
1195           struct ll_list list;
1196           struct element **elems;
1197           struct ll **elemp;
1198           int *values;
1199
1200           int *output;
1201           int *next_output;
1202
1203           int i;
1204
1205           allocate_ascending (cnt, &list, &elems, &elemp, &values);
1206           check_list_contents (&list, values, cnt);
1207
1208           output = next_output = xnmalloc (cnt, sizeof *output);
1209           ll_apply (elemp[r0], elemp[r1], apply_func, &next_output);
1210           check_list_contents (&list, values, cnt);
1211
1212           check (r1 - r0 == next_output - output);
1213           for (i = 0; i < r1 - r0; i++)
1214             check (output[i] == r0 + i);
1215
1216           free_elements (cnt, elems, elemp, values);
1217           free (output);
1218         }
1219 }
1220
1221 /* Tests ll_reverse. */
1222 static void
1223 test_reverse (void)
1224 {
1225   const int max_elems = 8;
1226
1227   int cnt, r0, r1;
1228
1229   for (cnt = 0; cnt <= max_elems; cnt++)
1230     for (r0 = 0; r0 <= cnt; r0++)
1231       for (r1 = r0; r1 <= cnt; r1++)
1232         {
1233           struct ll_list list;
1234           struct element **elems;
1235           struct ll **elemp;
1236           int *values;
1237
1238           int i, j;
1239
1240           allocate_ascending (cnt, &list, &elems, &elemp, &values);
1241           check_list_contents (&list, values, cnt);
1242
1243           j = 0;
1244           for (i = 0; i < r0; i++)
1245             values[j++] = i;
1246           for (i = r1 - 1; i >= r0; i--)
1247             values[j++] = i;
1248           for (i = r1; i < cnt; i++)
1249             values[j++] = i;
1250
1251           ll_reverse (elemp[r0], elemp[r1]);
1252           check_list_contents (&list, values, cnt);
1253
1254           free_elements (cnt, elems, elemp, values);
1255         }
1256 }
1257
1258 /* Tests ll_next_permutation and ll_prev_permutation when the
1259    permuted values have no duplicates. */
1260 static void
1261 test_permutations_no_dups (void)
1262 {
1263   const int max_elems = 8;
1264   int cnt;
1265
1266   for (cnt = 0; cnt <= max_elems; cnt++)
1267     {
1268       struct ll_list list;
1269       struct element **elems;
1270       int *values;
1271       int *old_values = xnmalloc (cnt, sizeof *values);
1272       int *new_values = xnmalloc (cnt, sizeof *values);
1273
1274       size_t perm_cnt;
1275
1276       allocate_ascending (cnt, &list, &elems, NULL, &values);
1277
1278       perm_cnt = 1;
1279       extract_values (&list, old_values, cnt);
1280       while (ll_next_permutation (ll_head (&list), ll_null (&list),
1281                                   compare_elements, &aux_data))
1282         {
1283           extract_values (&list, new_values, cnt);
1284           check (lexicographical_compare_3way (new_values, cnt,
1285                                                old_values, cnt,
1286                                                sizeof *new_values,
1287                                                compare_ints, NULL) > 0);
1288           memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1289           perm_cnt++;
1290         }
1291       check (perm_cnt == factorial (cnt));
1292       check_list_contents (&list, values, cnt);
1293
1294       perm_cnt = 1;
1295       ll_reverse (ll_head (&list), ll_null (&list));
1296       extract_values (&list, old_values, cnt);
1297       while (ll_prev_permutation (ll_head (&list), ll_null (&list),
1298                                   compare_elements, &aux_data))
1299         {
1300           extract_values (&list, new_values, cnt);
1301           check (lexicographical_compare_3way (new_values, cnt,
1302                                                old_values, cnt,
1303                                                sizeof *new_values,
1304                                                compare_ints, NULL) < 0);
1305           memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1306           perm_cnt++;
1307         }
1308       check (perm_cnt == factorial (cnt));
1309       ll_reverse (ll_head (&list), ll_null (&list));
1310       check_list_contents (&list, values, cnt);
1311
1312       free_elements (cnt, elems, NULL, values);
1313       free (old_values);
1314       free (new_values);
1315     }
1316 }
1317
1318 /* Tests ll_next_permutation and ll_prev_permutation when the
1319    permuted values contain duplicates. */
1320 static void
1321 test_permutations_with_dups (void)
1322 {
1323   const int max_elems = 8;
1324   const int max_dup = 3;
1325   const int repetitions = 1024;
1326
1327   int cnt, repeat;
1328
1329   for (repeat = 0; repeat < repetitions; repeat++)
1330     for (cnt = 0; cnt < max_elems; cnt++)
1331       {
1332         struct ll_list list;
1333         struct element **elems;
1334         int *values;
1335         int *old_values = xnmalloc (max_elems, sizeof *values);
1336         int *new_values = xnmalloc (max_elems, sizeof *values);
1337
1338         unsigned int permutation_cnt;
1339         int left = cnt;
1340         int value = 0;
1341
1342         allocate_elements (cnt, &list, &elems, NULL, &values);
1343
1344         value = 0;
1345         while (left > 0)
1346           {
1347             int max = left < max_dup ? left : max_dup;
1348             int n = rand () % max + 1;
1349             while (n-- > 0)
1350               {
1351                 int idx = cnt - left--;
1352                 values[idx] = elems[idx]->x = value;
1353               }
1354             value++;
1355           }
1356
1357         permutation_cnt = 1;
1358         extract_values (&list, old_values, cnt);
1359         while (ll_next_permutation (ll_head (&list), ll_null (&list),
1360                                     compare_elements, &aux_data))
1361           {
1362             extract_values (&list, new_values, cnt);
1363             check (lexicographical_compare_3way (new_values, cnt,
1364                                                  old_values, cnt,
1365                                                  sizeof *new_values,
1366                                                  compare_ints, NULL) > 0);
1367             memcpy (old_values, new_values, cnt * sizeof *old_values);
1368             permutation_cnt++;
1369           }
1370         check (permutation_cnt == expected_perms (values, cnt));
1371         check_list_contents (&list, values, cnt);
1372
1373         permutation_cnt = 1;
1374         ll_reverse (ll_head (&list), ll_null (&list));
1375         extract_values (&list, old_values, cnt);
1376         while (ll_prev_permutation (ll_head (&list), ll_null (&list),
1377                                     compare_elements, &aux_data))
1378           {
1379             extract_values (&list, new_values, cnt);
1380             check (lexicographical_compare_3way (new_values, cnt,
1381                                                  old_values, cnt,
1382                                                  sizeof *new_values,
1383                                                  compare_ints, NULL) < 0);
1384             permutation_cnt++;
1385           }
1386         ll_reverse (ll_head (&list), ll_null (&list));
1387         check (permutation_cnt == expected_perms (values, cnt));
1388         check_list_contents (&list, values, cnt);
1389
1390         free_elements (cnt, elems, NULL, values);
1391         free (old_values);
1392         free (new_values);
1393       }
1394 }
1395
1396 /* Tests ll_merge when no equal values are to be merged. */
1397 static void
1398 test_merge_no_dups (void)
1399 {
1400   const int max_elems = 8;
1401   const int max_filler = 3;
1402
1403   int merge_cnt, pattern, pfx, gap, sfx, order;
1404
1405   for (merge_cnt = 0; merge_cnt < max_elems; merge_cnt++)
1406     for (pattern = 0; pattern <= (1 << merge_cnt); pattern++)
1407       for (pfx = 0; pfx < max_filler; pfx++)
1408         for (gap = 0; gap < max_filler; gap++)
1409           for (sfx = 0; sfx < max_filler; sfx++)
1410             for (order = 0; order < 2; order++)
1411               {
1412                 struct ll_list list;
1413                 struct element **elems;
1414                 struct ll **elemp;
1415                 int *values;
1416
1417                 int list_cnt = pfx + merge_cnt + gap + sfx;
1418                 int a0, a1, b0, b1;
1419                 int i, j;
1420
1421                 allocate_elements (list_cnt, &list,
1422                                    &elems, &elemp, &values);
1423
1424                 j = 0;
1425                 for (i = 0; i < pfx; i++)
1426                   elems[j++]->x = 100 + i;
1427                 a0 = j;
1428                 for (i = 0; i < merge_cnt; i++)
1429                   if (pattern & (1u << i))
1430                     elems[j++]->x = i;
1431                 a1 = j;
1432                 for (i = 0; i < gap; i++)
1433                   elems[j++]->x = 200 + i;
1434                 b0 = j;
1435                 for (i = 0; i < merge_cnt; i++)
1436                   if (!(pattern & (1u << i)))
1437                     elems[j++]->x = i;
1438                 b1 = j;
1439                 for (i = 0; i < sfx; i++)
1440                   elems[j++]->x = 300 + i;
1441                 check (list_cnt == j);
1442
1443                 j = 0;
1444                 for (i = 0; i < pfx; i++)
1445                   values[j++] = 100 + i;
1446                 if (order == 0)
1447                   for (i = 0; i < merge_cnt; i++)
1448                     values[j++] = i;
1449                 for (i = 0; i < gap; i++)
1450                   values[j++] = 200 + i;
1451                 if (order == 1)
1452                   for (i = 0; i < merge_cnt; i++)
1453                     values[j++] = i;
1454                 for (i = 0; i < sfx; i++)
1455                   values[j++] = 300 + i;
1456                 check (list_cnt == j);
1457
1458                 if (order == 0)
1459                   ll_merge (elemp[a0], elemp[a1], elemp[b0], elemp[b1],
1460                             compare_elements, &aux_data);
1461                 else
1462                   ll_merge (elemp[b0], elemp[b1], elemp[a0], elemp[a1],
1463                             compare_elements, &aux_data);
1464
1465                 check_list_contents (&list, values, list_cnt);
1466
1467                 free_elements (list_cnt, elems, elemp, values);
1468               }
1469 }
1470
1471 /* Tests ll_merge when equal values are to be merged. */
1472 static void
1473 test_merge_with_dups (void)
1474 {
1475   const int max_elems = 8;
1476
1477   int cnt, merge_pat, inc_pat, order;
1478
1479   for (cnt = 0; cnt <= max_elems; cnt++)
1480     for (merge_pat = 0; merge_pat <= (1 << cnt); merge_pat++)
1481       for (inc_pat = 0; inc_pat <= (1 << cnt); inc_pat++)
1482         for (order = 0; order < 2; order++)
1483           {
1484             struct ll_list list;
1485             struct element **elems;
1486             struct ll **elemp;
1487             int *values;
1488
1489             int mid;
1490             int i, j, k;
1491
1492             allocate_elements (cnt, &list, &elems, &elemp, &values);
1493
1494             j = 0;
1495             for (i = k = 0; i < cnt; i++)
1496               {
1497                 if (merge_pat & (1u << i))
1498                   elems[j++]->x = k;
1499                 if (inc_pat & (1u << i))
1500                   k++;
1501               }
1502             mid = j;
1503             for (i = k = 0; i < cnt; i++)
1504               {
1505                 if (!(merge_pat & (1u << i)))
1506                   elems[j++]->x = k;
1507                 if (inc_pat & (1u << i))
1508                   k++;
1509               }
1510             check (cnt == j);
1511
1512             if (order == 0)
1513               {
1514                 for (i = 0; i < cnt; i++)
1515                   elems[i]->y = i;
1516               }
1517             else
1518               {
1519                 for (i = 0; i < mid; i++)
1520                   elems[i]->y = 100 + i;
1521                 for (i = mid; i < cnt; i++)
1522                   elems[i]->y = i;
1523               }
1524
1525             j = 0;
1526             for (i = k = 0; i < cnt; i++)
1527               {
1528                 values[j++] = k;
1529                 if (inc_pat & (1u << i))
1530                   k++;
1531               }
1532             check (cnt == j);
1533
1534             if (order == 0)
1535               ll_merge (elemp[0], elemp[mid], elemp[mid], elemp[cnt],
1536                         compare_elements, &aux_data);
1537             else
1538               ll_merge (elemp[mid], elemp[cnt], elemp[0], elemp[mid],
1539                         compare_elements, &aux_data);
1540
1541             check_list_contents (&list, values, cnt);
1542             check (ll_is_sorted (ll_head (&list), ll_null (&list),
1543                                  compare_elements_x_y, &aux_data));
1544
1545             free_elements (cnt, elems, elemp, values);
1546           }
1547 }
1548
1549 /* Tests ll_sort on all permutations up to a maximum number of
1550    elements. */
1551 static void
1552 test_sort_exhaustive (void)
1553 {
1554   const int max_elems = 8;
1555   int cnt;
1556
1557   for (cnt = 0; cnt <= max_elems; cnt++)
1558     {
1559       struct ll_list list;
1560       struct element **elems;
1561       int *values;
1562
1563       struct element **perm_elems;
1564       int *perm_values;
1565
1566       size_t perm_cnt;
1567
1568       allocate_ascending (cnt, &list, &elems, NULL, &values);
1569       allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1570
1571       perm_cnt = 1;
1572       while (ll_next_permutation (ll_head (&list), ll_null (&list),
1573                                   compare_elements, &aux_data))
1574         {
1575           struct ll_list perm_list;
1576           int j;
1577
1578           extract_values (&list, perm_values, cnt);
1579           ll_init (&perm_list);
1580           for (j = 0; j < cnt; j++)
1581             {
1582               perm_elems[j]->x = perm_values[j];
1583               ll_push_tail (&perm_list, &perm_elems[j]->ll);
1584             }
1585           ll_sort (ll_head (&perm_list), ll_null (&perm_list),
1586                    compare_elements, &aux_data);
1587           check_list_contents (&perm_list, values, cnt);
1588           check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1589                                compare_elements, &aux_data));
1590           perm_cnt++;
1591         }
1592       check (perm_cnt == factorial (cnt));
1593
1594       free_elements (cnt, elems, NULL, values);
1595       free_elements (cnt, perm_elems, NULL, perm_values);
1596     }
1597 }
1598
1599 /* Tests that ll_sort is stable in the presence of equal
1600    values. */
1601 static void
1602 test_sort_stable (void)
1603 {
1604   const int max_elems = 6;
1605   int cnt, inc_pat;
1606
1607   for (cnt = 0; cnt <= max_elems; cnt++)
1608     for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1609       {
1610         struct ll_list list;
1611         struct element **elems;
1612         int *values;
1613
1614         struct element **perm_elems;
1615         int *perm_values;
1616
1617         size_t perm_cnt;
1618         int i, j;
1619
1620         allocate_elements (cnt, &list, &elems, NULL, &values);
1621         allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1622
1623         j = 0;
1624         for (i = 0; i < cnt; i++)
1625           {
1626             elems[i]->x = values[i] = j;
1627             if (inc_pat & (1 << i))
1628               j++;
1629             elems[i]->y = i;
1630           }
1631
1632         perm_cnt = 1;
1633         while (ll_next_permutation (ll_head (&list), ll_null (&list),
1634                                     compare_elements_y, &aux_data))
1635           {
1636             struct ll_list perm_list;
1637
1638             extract_values (&list, perm_values, cnt);
1639             ll_init (&perm_list);
1640             for (i = 0; i < cnt; i++)
1641               {
1642                 perm_elems[i]->x = perm_values[i];
1643                 perm_elems[i]->y = i;
1644                 ll_push_tail (&perm_list, &perm_elems[i]->ll);
1645               }
1646             ll_sort (ll_head (&perm_list), ll_null (&perm_list),
1647                      compare_elements, &aux_data);
1648             check_list_contents (&perm_list, values, cnt);
1649             check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1650                                  compare_elements_x_y, &aux_data));
1651             perm_cnt++;
1652           }
1653         check (perm_cnt == factorial (cnt));
1654
1655         free_elements (cnt, elems, NULL, values);
1656         free_elements (cnt, perm_elems, NULL, perm_values);
1657       }
1658 }
1659
1660 /* Tests that ll_sort does not disturb elements outside the
1661    range sorted. */
1662 static void
1663 test_sort_subset (void)
1664 {
1665   const int max_elems = 8;
1666
1667   int cnt, r0, r1, repeat;
1668
1669   for (cnt = 0; cnt <= max_elems; cnt++)
1670     for (repeat = 0; repeat < 100; repeat++)
1671       for (r0 = 0; r0 <= cnt; r0++)
1672         for (r1 = r0; r1 <= cnt; r1++)
1673           {
1674             struct ll_list list;
1675             struct element **elems;
1676             struct ll **elemp;
1677             int *values;
1678
1679             allocate_random (cnt, &list, &elems, &elemp, &values);
1680
1681             qsort (&values[r0], r1 - r0, sizeof *values, compare_ints_noaux);
1682             ll_sort (elemp[r0], elemp[r1], compare_elements, &aux_data);
1683             check_list_contents (&list, values, cnt);
1684
1685             free_elements (cnt, elems, elemp, values);
1686           }
1687 }
1688
1689 /* Tests that ll_sort works with large lists. */
1690 static void
1691 test_sort_big (void)
1692 {
1693   const int max_elems = 1024;
1694
1695   int cnt;
1696
1697   for (cnt = 0; cnt < max_elems; cnt++)
1698     {
1699       struct ll_list list;
1700       struct element **elems;
1701       int *values;
1702
1703       allocate_random (cnt, &list, &elems, NULL, &values);
1704
1705       qsort (values, cnt, sizeof *values, compare_ints_noaux);
1706       ll_sort (ll_head (&list), ll_null (&list), compare_elements, &aux_data);
1707       check_list_contents (&list, values, cnt);
1708
1709       free_elements (cnt, elems, NULL, values);
1710     }
1711 }
1712
1713 /* Tests ll_unique. */
1714 static void
1715 test_unique (void)
1716 {
1717   const int max_elems = 10;
1718
1719   int *ascending = xnmalloc (max_elems, sizeof *ascending);
1720
1721   int cnt, inc_pat, i, j, unique_values;
1722
1723   for (i = 0; i < max_elems; i++)
1724     ascending[i] = i;
1725
1726   for (cnt = 0; cnt < max_elems; cnt++)
1727     for (inc_pat = 0; inc_pat < (1 << cnt); inc_pat++)
1728       {
1729         struct ll_list list, dups;
1730         struct element **elems;
1731         int *values;
1732
1733         allocate_elements (cnt, &list, &elems, NULL, &values);
1734
1735         j = unique_values = 0;
1736         for (i = 0; i < cnt; i++)
1737           {
1738             unique_values = j + 1;
1739             elems[i]->x = values[i] = j;
1740             if (inc_pat & (1 << i))
1741               j++;
1742           }
1743         check_list_contents (&list, values, cnt);
1744
1745         ll_init (&dups);
1746         check (ll_unique (ll_head (&list), ll_null (&list), ll_null (&dups),
1747                           compare_elements, &aux_data)
1748                == (size_t) unique_values);
1749         check_list_contents (&list, ascending, unique_values);
1750
1751         ll_splice (ll_null (&list), ll_head (&dups), ll_null (&dups));
1752         ll_sort (ll_head (&list), ll_null (&list), compare_elements, &aux_data);
1753         check_list_contents (&list, values, cnt);
1754
1755         free_elements (cnt, elems, NULL, values);
1756       }
1757
1758   free (ascending);
1759 }
1760
1761 /* Tests ll_sort_unique. */
1762 static void
1763 test_sort_unique (void)
1764 {
1765   const int max_elems = 7;
1766   int cnt, inc_pat;
1767
1768   for (cnt = 0; cnt <= max_elems; cnt++)
1769     for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1770       {
1771         struct ll_list list;
1772         struct element **elems;
1773         int *values;
1774
1775         struct element **perm_elems;
1776         int *perm_values;
1777
1778         int unique_cnt;
1779         int *unique_values;
1780
1781         size_t perm_cnt;
1782         int i, j;
1783
1784         allocate_elements (cnt, &list, &elems, NULL, &values);
1785         allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1786
1787         j = unique_cnt = 0;
1788         for (i = 0; i < cnt; i++)
1789           {
1790             elems[i]->x = values[i] = j;
1791             unique_cnt = j + 1;
1792             if (inc_pat & (1 << i))
1793               j++;
1794           }
1795
1796         unique_values = xnmalloc (unique_cnt, sizeof *unique_values);
1797         for (i = 0; i < unique_cnt; i++)
1798           unique_values[i] = i;
1799
1800         perm_cnt = 1;
1801         while (ll_next_permutation (ll_head (&list), ll_null (&list),
1802                                     compare_elements, &aux_data))
1803           {
1804             struct ll_list perm_list;
1805
1806             extract_values (&list, perm_values, cnt);
1807             ll_init (&perm_list);
1808             for (i = 0; i < cnt; i++)
1809               {
1810                 perm_elems[i]->x = perm_values[i];
1811                 perm_elems[i]->y = i;
1812                 ll_push_tail (&perm_list, &perm_elems[i]->ll);
1813               }
1814             ll_sort_unique (ll_head (&perm_list), ll_null (&perm_list), NULL,
1815                             compare_elements, &aux_data);
1816             check_list_contents (&perm_list, unique_values, unique_cnt);
1817             check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1818                                  compare_elements_x_y, &aux_data));
1819             perm_cnt++;
1820           }
1821         check (perm_cnt == expected_perms (values, cnt));
1822
1823         free_elements (cnt, elems, NULL, values);
1824         free_elements (cnt, perm_elems, NULL, perm_values);
1825         free (unique_values);
1826       }
1827 }
1828
1829 /* Tests ll_insert_ordered. */
1830 static void
1831 test_insert_ordered (void)
1832 {
1833   const int max_elems = 6;
1834   int cnt, inc_pat;
1835
1836   for (cnt = 0; cnt <= max_elems; cnt++)
1837     for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1838       {
1839         struct ll_list list;
1840         struct element **elems;
1841         int *values;
1842
1843         struct element **perm_elems;
1844         int *perm_values;
1845
1846         size_t perm_cnt;
1847         int i, j;
1848
1849         allocate_elements (cnt, &list, &elems, NULL, &values);
1850         allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1851
1852         j = 0;
1853         for (i = 0; i < cnt; i++)
1854           {
1855             elems[i]->x = values[i] = j;
1856             if (inc_pat & (1 << i))
1857               j++;
1858             elems[i]->y = i;
1859           }
1860
1861         perm_cnt = 1;
1862         while (ll_next_permutation (ll_head (&list), ll_null (&list),
1863                                     compare_elements_y, &aux_data))
1864           {
1865             struct ll_list perm_list;
1866
1867             extract_values (&list, perm_values, cnt);
1868             ll_init (&perm_list);
1869             for (i = 0; i < cnt; i++)
1870               {
1871                 perm_elems[i]->x = perm_values[i];
1872                 perm_elems[i]->y = i;
1873                 ll_insert_ordered (ll_head (&perm_list), ll_null (&perm_list),
1874                                    &perm_elems[i]->ll,
1875                                    compare_elements, &aux_data);
1876               }
1877             check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1878                                  compare_elements_x_y, &aux_data));
1879             perm_cnt++;
1880           }
1881         check (perm_cnt == factorial (cnt));
1882
1883         free_elements (cnt, elems, NULL, values);
1884         free_elements (cnt, perm_elems, NULL, perm_values);
1885       }
1886 }
1887
1888 /* Tests ll_partition. */
1889 static void
1890 test_partition (void)
1891 {
1892   const int max_elems = 10;
1893
1894   int cnt;
1895   unsigned int pbase;
1896   int r0, r1;
1897
1898   for (cnt = 0; cnt < max_elems; cnt++)
1899     for (r0 = 0; r0 <= cnt; r0++)
1900       for (r1 = r0; r1 <= cnt; r1++)
1901         for (pbase = 0; pbase <= (1u << (r1 - r0)); pbase++)
1902           {
1903             struct ll_list list;
1904             struct element **elems;
1905             struct ll **elemp;
1906             int *values;
1907
1908             unsigned int pattern = pbase << r0;
1909             int i, j;
1910             int first_false;
1911             struct ll *part_ll;
1912
1913             allocate_ascending (cnt, &list, &elems, &elemp, &values);
1914
1915             /* Check that ll_find_partition works okay in every
1916                case.  We use it after partitioning, too, but that
1917                only tests cases where it returns non-null. */
1918             for (i = r0; i < r1; i++)
1919               if (!(pattern & (1u << i)))
1920                 break;
1921             j = i;
1922             for (; i < r1; i++)
1923               if (pattern & (1u << i))
1924                 break;
1925             part_ll = ll_find_partition (elemp[r0], elemp[r1],
1926                                          pattern_pred,
1927                                          &pattern);
1928             if (i == r1)
1929               check (part_ll == elemp[j]);
1930             else
1931               check (part_ll == NULL);
1932
1933             /* Figure out expected results. */
1934             j = 0;
1935             first_false = -1;
1936             for (i = 0; i < r0; i++)
1937               values[j++] = i;
1938             for (i = r0; i < r1; i++)
1939               if (pattern & (1u << i))
1940                 values[j++] = i;
1941             for (i = r0; i < r1; i++)
1942               if (!(pattern & (1u << i)))
1943                 {
1944                   if (first_false == -1)
1945                     first_false = i;
1946                   values[j++] = i;
1947                 }
1948             if (first_false == -1)
1949               first_false = r1;
1950             for (i = r1; i < cnt; i++)
1951               values[j++] = i;
1952             check (j == cnt);
1953
1954             /* Partition and check for expected results. */
1955             check (ll_partition (elemp[r0], elemp[r1],
1956                                  pattern_pred, &pattern)
1957                    == elemp[first_false]);
1958             check (ll_find_partition (elemp[r0], elemp[r1],
1959                                       pattern_pred, &pattern)
1960                    == elemp[first_false]);
1961             check_list_contents (&list, values, cnt);
1962             check ((int) ll_count (&list) == cnt);
1963
1964             free_elements (cnt, elems, elemp, values);
1965           }
1966 }
1967 \f
1968 /* Main program. */
1969
1970 struct test
1971   {
1972     const char *name;
1973     const char *description;
1974     void (*function) (void);
1975   };
1976
1977 static const struct test tests[] =
1978   {
1979     {
1980       "push-pop",
1981       "push/pop",
1982       test_push_pop
1983     },
1984     {
1985       "insert-remove",
1986       "insert/remove",
1987       test_insert_remove
1988     },
1989     {
1990       "swap",
1991       "swap",
1992       test_swap
1993     },
1994     {
1995       "swap-range",
1996       "swap_range",
1997       test_swap_range
1998     },
1999     {
2000       "remove-range",
2001       "remove_range",
2002       test_remove_range
2003     },
2004     {
2005       "remove-equal",
2006       "remove_equal",
2007       test_remove_equal
2008     },
2009     {
2010       "remove-if",
2011       "remove_if",
2012       test_remove_if
2013     },
2014     {
2015       "moved",
2016       "moved",
2017       test_moved
2018     },
2019     {
2020       "find-equal",
2021       "find_equal",
2022       test_find_equal
2023     },
2024     {
2025       "find-if",
2026       "find_if",
2027       test_find_if
2028     },
2029     {
2030       "find-adjacent-equal",
2031       "find_adjacent_equal",
2032       test_find_adjacent_equal
2033     },
2034     {
2035       "count-range",
2036       "count_range",
2037       test_count_range
2038     },
2039     {
2040       "count-equal",
2041       "count_equal",
2042       test_count_equal
2043     },
2044     {
2045       "count-if",
2046       "count_if",
2047       test_count_if
2048     },
2049     {
2050       "min-max",
2051       "min/max",
2052       test_min_max
2053     },
2054     {
2055       "lexicographical-compare-3way",
2056       "lexicographical_compare_3way",
2057       test_lexicographical_compare_3way
2058     },
2059     {
2060       "apply",
2061       "apply",
2062       test_apply
2063     },
2064     {
2065       "reverse",
2066       "reverse",
2067       test_reverse
2068     },
2069     {
2070       "permutations-no-dups",
2071       "permutations (no dups)",
2072       test_permutations_no_dups
2073     },
2074     {
2075       "permutations-with-dups",
2076       "permutations (with dups)",
2077       test_permutations_with_dups
2078     },
2079     {
2080       "merge-no-dups",
2081       "merge (no dups)",
2082       test_merge_no_dups
2083     },
2084     {
2085       "merge-with-dups",
2086       "merge (with dups)",
2087       test_merge_with_dups
2088     },
2089     {
2090       "sort-exhaustive",
2091       "sort (exhaustive)",
2092       test_sort_exhaustive
2093     },
2094     {
2095       "sort-stable",
2096       "sort (stability)",
2097       test_sort_stable
2098     },
2099     {
2100       "sort-subset",
2101       "sort (subset)",
2102       test_sort_subset
2103     },
2104     {
2105       "sort-big",
2106       "sort (big)",
2107       test_sort_big
2108     },
2109     {
2110       "unique",
2111       "unique",
2112       test_unique
2113     },
2114     {
2115       "sort-unique",
2116       "sort_unique",
2117       test_sort_unique
2118     },
2119     {
2120       "insert-ordered",
2121       "insert_ordered",
2122       test_insert_ordered
2123     },
2124     {
2125       "partition",
2126       "partition",
2127       test_partition
2128     },
2129   };
2130
2131 enum { N_TESTS = sizeof tests / sizeof *tests };
2132
2133 int
2134 main (int argc, char *argv[])
2135 {
2136   int i;
2137
2138   if (argc != 2)
2139     {
2140       fprintf (stderr, "exactly one argument required; use --help for help\n");
2141       return EXIT_FAILURE;
2142     }
2143   else if (!strcmp (argv[1], "--help"))
2144     {
2145       printf ("%s: test doubly linked list (ll) library\n"
2146               "usage: %s TEST-NAME\n"
2147               "where TEST-NAME is one of the following:\n",
2148               argv[0], argv[0]);
2149       for (i = 0; i < N_TESTS; i++)
2150         printf ("  %s\n    %s\n", tests[i].name, tests[i].description);
2151       return 0;
2152     }
2153   else
2154     {
2155       for (i = 0; i < N_TESTS; i++)
2156         if (!strcmp (argv[1], tests[i].name))
2157           {
2158             tests[i].function ();
2159             return 0;
2160           }
2161
2162       fprintf (stderr, "unknown test %s; use --help for help\n", argv[1]);
2163       return EXIT_FAILURE;
2164     }
2165 }