/* PSPP - a program for statistical analysis.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#endif
#include <libpspp/llx.h>
-#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define UNUSED
#endif
-/* Currently running test. */
-static const char *test_name;
-
/* Exit with a failure code.
(Place a breakpoint on this function while debugging.) */
static void
{
if (!ok)
{
- printf ("Check failed in %s test at %s, line %d\n",
- test_name, __FILE__, line);
+ fprintf (stderr, "%s:%d: check failed\n", __FILE__, line);
check_die ();
}
}
test_examine_equal_range (test_find_equal_helper);
}
+/* Tests llx_find(). */
+static void
+test_find (void)
+{
+ const int max_elems = 8;
+
+ int cnt;
+
+ for (cnt = 0; cnt <= max_elems; cnt++)
+ {
+ struct llx_list list;
+ struct element **elems;
+ struct llx **elemp;
+ int *values;
+
+ int i;
+
+ allocate_ascending (cnt, &list, &elems, &elemp, &values);
+
+ for (i = 0; i < cnt; i++)
+ check (llx_find (llx_head (&list), llx_null (&list), elems[i])
+ == elemp[i]);
+ check (llx_find (llx_head (&list), llx_null (&list), NULL) == NULL);
+
+ free_elements (cnt, &list, elems, elemp, values);
+ }
+}
+
/* Helper function for testing llx_find_if. */
static void
test_find_if_helper (int r0, int r1, int eq_pat, struct llx **elemp)
expected_perms (int *values, size_t cnt)
{
size_t i, j;
- unsigned int perm_cnt;
+ unsigned int n_perms;
- perm_cnt = factorial (cnt);
+ n_perms = factorial (cnt);
for (i = 0; i < cnt; i = j)
{
for (j = i + 1; j < cnt; j++)
if (values[i] != values[j])
break;
- perm_cnt /= factorial (j - i);
+ n_perms /= factorial (j - i);
}
- return perm_cnt;
+ return n_perms;
}
/* Tests llx_min and llx_max. */
int *values;
int *new_values = xnmalloc (cnt, sizeof *values);
- size_t perm_cnt;
+ size_t n_perms;
allocate_ascending (cnt, &list, &elems, &elemp, &values);
- perm_cnt = 1;
+ n_perms = 1;
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements, &aux_data))
{
check (max != elemp[r1] && max_elem->x == max_int);
}
}
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == factorial (cnt));
+ check (n_perms == factorial (cnt));
check_list_contents (&list, values, cnt);
free_elements (cnt, &list, elems, elemp, values);
int *old_values = xnmalloc (cnt, sizeof *values);
int *new_values = xnmalloc (cnt, sizeof *values);
- size_t perm_cnt;
+ size_t n_perms;
allocate_ascending (cnt, &list, &elems, NULL, &values);
- perm_cnt = 1;
+ n_perms = 1;
extract_values (&list, old_values, cnt);
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements, &aux_data))
sizeof *new_values,
compare_ints, NULL) > 0);
memcpy (old_values, new_values, (cnt) * sizeof *old_values);
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == factorial (cnt));
+ check (n_perms == factorial (cnt));
check_list_contents (&list, values, cnt);
- perm_cnt = 1;
+ n_perms = 1;
llx_reverse (llx_head (&list), llx_null (&list));
extract_values (&list, old_values, cnt);
while (llx_prev_permutation (llx_head (&list), llx_null (&list),
sizeof *new_values,
compare_ints, NULL) < 0);
memcpy (old_values, new_values, (cnt) * sizeof *old_values);
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == factorial (cnt));
+ check (n_perms == factorial (cnt));
llx_reverse (llx_head (&list), llx_null (&list));
check_list_contents (&list, values, cnt);
int *old_values = xnmalloc (max_elems, sizeof *values);
int *new_values = xnmalloc (max_elems, sizeof *values);
- unsigned int permutation_cnt;
+ unsigned int n_permutations;
int left = cnt;
int value = 0;
value++;
}
- permutation_cnt = 1;
+ n_permutations = 1;
extract_values (&list, old_values, cnt);
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements, &aux_data))
sizeof *new_values,
compare_ints, NULL) > 0);
memcpy (old_values, new_values, cnt * sizeof *old_values);
- permutation_cnt++;
+ n_permutations++;
}
- check (permutation_cnt == expected_perms (values, cnt));
+ check (n_permutations == expected_perms (values, cnt));
check_list_contents (&list, values, cnt);
- permutation_cnt = 1;
+ n_permutations = 1;
llx_reverse (llx_head (&list), llx_null (&list));
extract_values (&list, old_values, cnt);
while (llx_prev_permutation (llx_head (&list), llx_null (&list),
old_values, cnt,
sizeof *new_values,
compare_ints, NULL) < 0);
- permutation_cnt++;
+ n_permutations++;
}
llx_reverse (llx_head (&list), llx_null (&list));
- check (permutation_cnt == expected_perms (values, cnt));
+ check (n_permutations == expected_perms (values, cnt));
check_list_contents (&list, values, cnt);
free_elements (cnt, &list, elems, elemp, values);
const int max_elems = 8;
const int max_fillxer = 3;
- int merge_cnt, pattern, pfx, gap, sfx, order;
+ int n_merges, pattern, pfx, gap, sfx, order;
- for (merge_cnt = 0; merge_cnt < max_elems; merge_cnt++)
- for (pattern = 0; pattern <= (1 << merge_cnt); pattern++)
+ for (n_merges = 0; n_merges < max_elems; n_merges++)
+ for (pattern = 0; pattern <= (1 << n_merges); pattern++)
for (pfx = 0; pfx < max_fillxer; pfx++)
for (gap = 0; gap < max_fillxer; gap++)
for (sfx = 0; sfx < max_fillxer; sfx++)
struct llx **elemp;
int *values;
- int list_cnt = pfx + merge_cnt + gap + sfx;
+ int n_lists = pfx + n_merges + gap + sfx;
int a0, a1, b0, b1;
int i, j;
- allocate_elements (list_cnt, &list,
+ allocate_elements (n_lists, &list,
&elems, &elemp, &values);
j = 0;
for (i = 0; i < pfx; i++)
elems[j++]->x = 100 + i;
a0 = j;
- for (i = 0; i < merge_cnt; i++)
+ for (i = 0; i < n_merges; i++)
if (pattern & (1u << i))
elems[j++]->x = i;
a1 = j;
for (i = 0; i < gap; i++)
elems[j++]->x = 200 + i;
b0 = j;
- for (i = 0; i < merge_cnt; i++)
+ for (i = 0; i < n_merges; i++)
if (!(pattern & (1u << i)))
elems[j++]->x = i;
b1 = j;
for (i = 0; i < sfx; i++)
elems[j++]->x = 300 + i;
- check (list_cnt == j);
+ check (n_lists == j);
j = 0;
for (i = 0; i < pfx; i++)
values[j++] = 100 + i;
if (order == 0)
- for (i = 0; i < merge_cnt; i++)
+ for (i = 0; i < n_merges; i++)
values[j++] = i;
for (i = 0; i < gap; i++)
values[j++] = 200 + i;
if (order == 1)
- for (i = 0; i < merge_cnt; i++)
+ for (i = 0; i < n_merges; i++)
values[j++] = i;
for (i = 0; i < sfx; i++)
values[j++] = 300 + i;
- check (list_cnt == j);
+ check (n_lists == j);
if (order == 0)
llx_merge (elemp[a0], elemp[a1], elemp[b0], elemp[b1],
llx_merge (elemp[b0], elemp[b1], elemp[a0], elemp[a1],
compare_elements, &aux_data);
- check_list_contents (&list, values, list_cnt);
+ check_list_contents (&list, values, n_lists);
- free_elements (list_cnt, &list, elems, elemp, values);
+ free_elements (n_lists, &list, elems, elemp, values);
}
}
struct element **perm_elems;
int *perm_values;
- size_t perm_cnt;
+ size_t n_perms;
allocate_ascending (cnt, &list, &elems, NULL, &values);
allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
- perm_cnt = 1;
+ n_perms = 1;
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements, &aux_data))
{
check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
compare_elements, &aux_data));
llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == factorial (cnt));
+ check (n_perms == factorial (cnt));
free_elements (cnt, &list, elems, NULL, values);
free_elements (cnt, NULL, perm_elems, NULL, perm_values);
struct element **perm_elems;
int *perm_values;
- size_t perm_cnt;
+ size_t n_perms;
int i, j;
allocate_elements (cnt, &list, &elems, NULL, &values);
elems[i]->y = i;
}
- perm_cnt = 1;
+ n_perms = 1;
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements_y, &aux_data))
{
check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
compare_elements_x_y, &aux_data));
llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == factorial (cnt));
+ check (n_perms == factorial (cnt));
free_elements (cnt, &list, elems, NULL, values);
free_elements (cnt, NULL, perm_elems, NULL, perm_values);
struct element **perm_elems;
int *perm_values;
- int unique_cnt;
+ int n_uniques;
int *unique_values;
- size_t perm_cnt;
+ size_t n_perms;
int i, j;
allocate_elements (cnt, &list, &elems, NULL, &values);
allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
- j = unique_cnt = 0;
+ j = n_uniques = 0;
for (i = 0; i < cnt; i++)
{
elems[i]->x = values[i] = j;
- unique_cnt = j + 1;
+ n_uniques = j + 1;
if (inc_pat & (1 << i))
j++;
}
- unique_values = xnmalloc (unique_cnt, sizeof *unique_values);
- for (i = 0; i < unique_cnt; i++)
+ unique_values = xnmalloc (n_uniques, sizeof *unique_values);
+ for (i = 0; i < n_uniques; i++)
unique_values[i] = i;
- perm_cnt = 1;
+ n_perms = 1;
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements, &aux_data))
{
llx_sort_unique (llx_head (&perm_list), llx_null (&perm_list), NULL,
compare_elements, &aux_data,
&llx_malloc_mgr);
- check_list_contents (&perm_list, unique_values, unique_cnt);
+ check_list_contents (&perm_list, unique_values, n_uniques);
check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
compare_elements_x_y, &aux_data));
llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == expected_perms (values, cnt));
+ check (n_perms == expected_perms (values, cnt));
free_elements (cnt, &list, elems, NULL, values);
free_elements (cnt, NULL, perm_elems, NULL, perm_values);
struct element **perm_elems;
int *perm_values;
- size_t perm_cnt;
+ size_t n_perms;
int i, j;
allocate_elements (cnt, &list, &elems, NULL, &values);
elems[i]->y = i;
}
- perm_cnt = 1;
+ n_perms = 1;
while (llx_next_permutation (llx_head (&list), llx_null (&list),
compare_elements_y, &aux_data))
{
check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
compare_elements_x_y, &aux_data));
llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
- perm_cnt++;
+ n_perms++;
}
- check (perm_cnt == factorial (cnt));
+ check (n_perms == factorial (cnt));
free_elements (cnt, &list, elems, NULL, values);
free_elements (cnt, NULL, perm_elems, NULL, perm_values);
\f
/* Main program. */
-/* Runs TEST_FUNCTION and prints a message about NAME. */
-static void
-run_test (void (*test_function) (void), const char *name)
-{
- test_name = name;
- putchar ('.');
- fflush (stdout);
- test_function ();
-}
+struct test
+ {
+ const char *name;
+ const char *description;
+ void (*function) (void);
+ };
+
+static const struct test tests[] =
+ {
+ {
+ "push-pop",
+ "push/pop",
+ test_push_pop
+ },
+ {
+ "insert-remove",
+ "insert/remove",
+ test_insert_remove
+ },
+ {
+ "swap",
+ "swap",
+ test_swap
+ },
+ {
+ "swap-range",
+ "swap_range",
+ test_swap_range
+ },
+ {
+ "remove-range",
+ "remove_range",
+ test_remove_range
+ },
+ {
+ "remove-equal",
+ "remove_equal",
+ test_remove_equal
+ },
+ {
+ "remove-if",
+ "remove_if",
+ test_remove_if
+ },
+ {
+ "find-equal",
+ "find_equal",
+ test_find_equal
+ },
+ {
+ "find",
+ "find",
+ test_find
+ },
+ {
+ "find-if",
+ "find_if",
+ test_find_if
+ },
+ {
+ "find-adjacent-equal",
+ "find_adjacent_equal",
+ test_find_adjacent_equal
+ },
+ {
+ "count-range",
+ "count_range",
+ test_count_range
+ },
+ {
+ "count-equal",
+ "count_equal",
+ test_count_equal
+ },
+ {
+ "count-if",
+ "count_if",
+ test_count_if
+ },
+ {
+ "min-max",
+ "min/max",
+ test_min_max
+ },
+ {
+ "lexicographical-compare-3way",
+ "lexicographical_compare_3way",
+ test_lexicographical_compare_3way
+ },
+ {
+ "apply",
+ "apply",
+ test_apply
+ },
+ {
+ "destroy",
+ "destroy",
+ test_destroy
+ },
+ {
+ "reverse",
+ "reverse",
+ test_reverse
+ },
+ {
+ "permutations-no-dups",
+ "permutations (no dups)",
+ test_permutations_no_dups
+ },
+ {
+ "permutations-with-dups",
+ "permutations (with dups)",
+ test_permutations_with_dups
+ },
+ {
+ "merge-no-dups",
+ "merge (no dups)",
+ test_merge_no_dups
+ },
+ {
+ "merge-with-dups",
+ "merge (with dups)",
+ test_merge_with_dups
+ },
+ {
+ "sort-exhaustive",
+ "sort (exhaustive)",
+ test_sort_exhaustive
+ },
+ {
+ "sort-stable",
+ "sort (stability)",
+ test_sort_stable
+ },
+ {
+ "sort-subset",
+ "sort (subset)",
+ test_sort_subset
+ },
+ {
+ "sort-big",
+ "sort (big)",
+ test_sort_big
+ },
+ {
+ "unique",
+ "unique",
+ test_unique
+ },
+ {
+ "sort-unique",
+ "sort_unique",
+ test_sort_unique
+ },
+ {
+ "insert-ordered",
+ "insert_ordered",
+ test_insert_ordered
+ },
+ {
+ "partition",
+ "partition",
+ test_partition
+ },
+ {
+ "allocation-failure",
+ "allocation failure",
+ test_allocation_failure
+ },
+ };
+
+enum { N_TESTS = sizeof tests / sizeof *tests };
int
-main (void)
-{
- run_test (test_push_pop, "push/pop");
- run_test (test_insert_remove, "insert/remove");
- run_test (test_swap, "swap");
- run_test (test_swap_range, "swap_range");
- run_test (test_remove_range, "remove_range");
- run_test (test_remove_equal, "remove_equal");
- run_test (test_remove_if, "remove_if");
- run_test (test_find_equal, "find_equal");
- run_test (test_find_if, "find_if");
- run_test (test_find_adjacent_equal, "find_adjacent_equal");
- run_test (test_count_range, "count_range");
- run_test (test_count_equal, "count_equal");
- run_test (test_count_if, "count_if");
- run_test (test_min_max, "min/max");
- run_test (test_lexicographical_compare_3way, "lexicographical_compare_3way");
- run_test (test_apply, "apply");
- run_test (test_destroy, "destroy");
- run_test (test_reverse, "reverse");
- run_test (test_permutations_no_dups, "permutations (no dups)");
- run_test (test_permutations_with_dups, "permutations (with dups)");
- run_test (test_merge_no_dups, "merge (no dups)");
- run_test (test_merge_with_dups, "merge (with dups)");
- run_test (test_sort_exhaustive, "sort (exhaustive)");
- run_test (test_sort_stable, "sort (stability)");
- run_test (test_sort_subset, "sort (subset)");
- run_test (test_sort_big, "sort (big)");
- run_test (test_unique, "unique");
- run_test (test_sort_unique, "sort_unique");
- run_test (test_insert_ordered, "insert_ordered");
- run_test (test_partition, "partition");
- run_test (test_allocation_failure, "allocation failure");
- putchar ('\n');
-
- return 0;
-}
-
-/*
- Local Variables:
- compile-command: "gcc -Wall -Wstrict-prototypes -Wmissing-prototypes ll.c llx.c llx-test.c -o llx-test -g"
- End:
- */
+main (int argc, char *argv[])
+{
+ int i;
+
+ if (argc != 2)
+ {
+ fprintf (stderr, "exactly one argument required; use --help for help\n");
+ return EXIT_FAILURE;
+ }
+ else if (!strcmp (argv[1], "--help"))
+ {
+ printf ("%s: test doubly linked list of pointers (llx) library\n"
+ "usage: %s TEST-NAME\n"
+ "where TEST-NAME is one of the following:\n",
+ argv[0], argv[0]);
+ for (i = 0; i < N_TESTS; i++)
+ printf (" %s\n %s\n", tests[i].name, tests[i].description);
+ return 0;
+ }
+ else
+ {
+ for (i = 0; i < N_TESTS; i++)
+ if (!strcmp (argv[1], tests[i].name))
+ {
+ tests[i].function ();
+ return 0;
+ }
+
+ fprintf (stderr, "unknown test %s; use --help for help\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+}