lexer: New functions for parsing real numbers in specified ranges.
[pspp] / tests / libpspp / string-set-test.c
index 6aafef445b9fe2c4b366407b219c2addc321732f..2ba349dced43c8fb334b50213f559a41f56b38d5 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 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
 
    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
@@ -36,9 +36,6 @@
 
 #include <libpspp/compiler.h>
 \f
 
 #include <libpspp/compiler.h>
 \f
-/* Currently running test. */
-static const char *test_name;
-
 /* Exit with a failure code.
    (Place a breakpoint on this function while debugging.) */
 static void
 /* Exit with a failure code.
    (Place a breakpoint on this function while debugging.) */
 static void
@@ -54,8 +51,7 @@ check_func (bool ok, int line)
 {
   if (!ok)
     {
 {
   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 ();
     }
 }
       check_die ();
     }
 }
@@ -157,18 +153,18 @@ swap (int *a, int *b)
   *b = t;
 }
 
   *b = t;
 }
 
-/* Reverses the order of the CNT integers starting at VALUES. */
+/* Reverses the order of the N integers starting at VALUES. */
 static void
 static void
-reverse (int *values, size_t cnt)
+reverse (int *values, size_t n)
 {
   size_t i = 0;
 {
   size_t i = 0;
-  size_t j = cnt;
+  size_t j = n;
 
   while (j > i)
     swap (&values[i++], &values[--j]);
 }
 
 
   while (j > i)
     swap (&values[i++], &values[--j]);
 }
 
-/* Arranges the CNT elements in VALUES into the lexicographically
+/* Arranges the N elements in VALUES into the lexicographically
    next greater permutation.  Returns true if successful.
    If VALUES is already the lexicographically greatest
    permutation of its elements (i.e. ordered from greatest to
    next greater permutation.  Returns true if successful.
    If VALUES is already the lexicographically greatest
    permutation of its elements (i.e. ordered from greatest to
@@ -176,26 +172,26 @@ reverse (int *values, size_t cnt)
    permutation (i.e. ordered from smallest to largest) and
    returns false. */
 static bool
    permutation (i.e. ordered from smallest to largest) and
    returns false. */
 static bool
-next_permutation (int *values, size_t cnt)
+next_permutation (int *values, size_t n)
 {
 {
-  if (cnt > 0)
+  if (n > 0)
     {
     {
-      size_t i = cnt - 1;
+      size_t i = n - 1;
       while (i != 0)
         {
           i--;
           if (values[i] < values[i + 1])
             {
               size_t j;
       while (i != 0)
         {
           i--;
           if (values[i] < values[i + 1])
             {
               size_t j;
-              for (j = cnt - 1; values[i] >= values[j]; j--)
+              for (j = n - 1; values[i] >= values[j]; j--)
                 continue;
               swap (values + i, values + j);
                 continue;
               swap (values + i, values + j);
-              reverse (values + (i + 1), cnt - (i + 1));
+              reverse (values + (i + 1), n - (i + 1));
               return true;
             }
         }
 
               return true;
             }
         }
 
-      reverse (values, cnt);
+      reverse (values, n);
     }
 
   return false;
     }
 
   return false;
@@ -211,18 +207,18 @@ factorial (unsigned int n)
   return value;
 }
 
   return value;
 }
 
-/* Randomly shuffles the CNT elements in ARRAY, each of which is
+/* Randomly shuffles the N elements in ARRAY, each of which is
    SIZE bytes in size. */
 static void
    SIZE bytes in size. */
 static void
-random_shuffle (void *array_, size_t cnt, size_t size)
+random_shuffle (void *array_, size_t n, size_t size)
 {
   char *array = array_;
   char *tmp = xmalloc (size);
   size_t i;
 
 {
   char *array = array_;
   char *tmp = xmalloc (size);
   size_t i;
 
-  for (i = 0; i < cnt; i++)
+  for (i = 0; i < n; i++)
     {
     {
-      size_t j = rand () % (cnt - i) + i;
+      size_t j = rand () % (n - i) + i;
       if (i != j)
         {
           memcpy (tmp, array + j * size, size);
       if (i != j)
         {
           memcpy (tmp, array + j * size, size);
@@ -234,17 +230,17 @@ random_shuffle (void *array_, size_t cnt, size_t size)
   free (tmp);
 }
 
   free (tmp);
 }
 
-/* Checks that SET contains the CNT strings in DATA, that its structure is
+/* Checks that SET contains the N strings in DATA, that its structure is
    correct, and that certain operations on SET produce the expected results. */
 static void
    correct, and that certain operations on SET produce the expected results. */
 static void
-check_string_set (struct string_set *set, const int data[], size_t cnt)
+check_string_set (struct string_set *set, const int data[], size_t n)
 {
   size_t i;
 
 {
   size_t i;
 
-  check (string_set_is_empty (set) == (cnt == 0));
-  check (string_set_count (set) == cnt);
+  check (string_set_is_empty (set) == (n == 0));
+  check (string_set_count (set) == n);
 
 
-  for (i = 0; i < cnt; i++)
+  for (i = 0; i < n; i++)
     {
       struct string_set_node *node;
       const char *s = make_string (data[i]);
     {
       struct string_set_node *node;
       const char *s = make_string (data[i]);
@@ -261,7 +257,7 @@ check_string_set (struct string_set *set, const int data[], size_t cnt)
   check (!string_set_contains (set, "xxx"));
   check (string_set_find_node (set, "") == NULL);
 
   check (!string_set_contains (set, "xxx"));
   check (string_set_find_node (set, "") == NULL);
 
-  if (cnt == 0)
+  if (n == 0)
     check (string_set_first (set) == NULL);
   else
     {
     check (string_set_first (set) == NULL);
   else
     {
@@ -269,9 +265,9 @@ check_string_set (struct string_set *set, const int data[], size_t cnt)
       int *data_copy;
       int left;
 
       int *data_copy;
       int left;
 
-      data_copy = xmemdup (data, cnt * sizeof *data);
-      left = cnt;
-      for (node = string_set_first (set), i = 0; i < cnt;
+      data_copy = xmemdup (data, n * sizeof *data);
+      left = n;
+      for (node = string_set_first (set), i = 0; i < n;
            node = string_set_next (set, node), i++)
         {
           const char *s = string_set_node_get_string (node);
            node = string_set_next (set, node), i++)
         {
           const char *s = string_set_node_get_string (node);
@@ -292,29 +288,29 @@ check_string_set (struct string_set *set, const int data[], size_t cnt)
     }
 }
 
     }
 }
 
-/* Inserts the CNT strings from 0 to CNT - 1 (inclusive) into a set in the
+/* Inserts the N strings from 0 to N - 1 (inclusive) into a set in the
    order specified by INSERTIONS, then deletes them in the order specified by
    DELETIONS, checking the set's contents for correctness after each
    operation.  */
 static void
 test_insert_delete (const int insertions[],
                     const int deletions[],
    order specified by INSERTIONS, then deletes them in the order specified by
    DELETIONS, checking the set's contents for correctness after each
    operation.  */
 static void
 test_insert_delete (const int insertions[],
                     const int deletions[],
-                    size_t cnt)
+                    size_t n)
 {
   struct string_set set;
   size_t i;
 
   string_set_init (&set);
   check_string_set (&set, NULL, 0);
 {
   struct string_set set;
   size_t i;
 
   string_set_init (&set);
   check_string_set (&set, NULL, 0);
-  for (i = 0; i < cnt; i++)
+  for (i = 0; i < n; i++)
     {
       check (string_set_insert (&set, make_string (insertions[i])));
       check_string_set (&set, insertions, i + 1);
     }
     {
       check (string_set_insert (&set, make_string (insertions[i])));
       check_string_set (&set, insertions, i + 1);
     }
-  for (i = 0; i < cnt; i++)
+  for (i = 0; i < n; i++)
     {
       check (string_set_delete (&set, make_string (deletions[i])));
     {
       check (string_set_delete (&set, make_string (deletions[i])));
-      check_string_set (&set, deletions + i + 1, cnt - i - 1);
+      check_string_set (&set, deletions + i + 1, n - i - 1);
     }
   string_set_destroy (&set);
 }
     }
   string_set_destroy (&set);
 }
@@ -325,37 +321,37 @@ static void
 test_insert_any_remove_any (void)
 {
   const int max_elems = 5;
 test_insert_any_remove_any (void)
 {
   const int max_elems = 5;
-  int cnt;
+  int n;
 
 
-  for (cnt = 0; cnt <= max_elems; cnt++)
+  for (n = 0; n <= max_elems; n++)
     {
       int *insertions, *deletions;
     {
       int *insertions, *deletions;
-      unsigned int ins_perm_cnt;
+      unsigned int ins_n_perms;
       int i;
 
       int i;
 
-      insertions = xnmalloc (cnt, sizeof *insertions);
-      deletions = xnmalloc (cnt, sizeof *deletions);
-      for (i = 0; i < cnt; i++)
+      insertions = xnmalloc (n, sizeof *insertions);
+      deletions = xnmalloc (n, sizeof *deletions);
+      for (i = 0; i < n; i++)
         insertions[i] = i;
 
         insertions[i] = i;
 
-      for (ins_perm_cnt = 0;
-           ins_perm_cnt == 0 || next_permutation (insertions, cnt);
-           ins_perm_cnt++)
+      for (ins_n_perms = 0;
+           ins_n_perms == 0 || next_permutation (insertions, n);
+           ins_n_perms++)
         {
         {
-          unsigned int del_perm_cnt;
+          unsigned int del_n_perms;
           int i;
 
           int i;
 
-          for (i = 0; i < cnt; i++)
+          for (i = 0; i < n; i++)
             deletions[i] = i;
 
             deletions[i] = i;
 
-          for (del_perm_cnt = 0;
-               del_perm_cnt == 0 || next_permutation (deletions, cnt);
-               del_perm_cnt++)
-            test_insert_delete (insertions, deletions, cnt);
+          for (del_n_perms = 0;
+               del_n_perms == 0 || next_permutation (deletions, n);
+               del_n_perms++)
+            test_insert_delete (insertions, deletions, n);
 
 
-          check (del_perm_cnt == factorial (cnt));
+          check (del_n_perms == factorial (n));
         }
         }
-      check (ins_perm_cnt == factorial (cnt));
+      check (ins_n_perms == factorial (n));
 
       free (insertions);
       free (deletions);
 
       free (insertions);
       free (deletions);
@@ -368,23 +364,23 @@ static void
 test_insert_any_remove_same (void)
 {
   const int max_elems = 7;
 test_insert_any_remove_same (void)
 {
   const int max_elems = 7;
-  int cnt;
+  int n;
 
 
-  for (cnt = 0; cnt <= max_elems; cnt++)
+  for (n = 0; n <= max_elems; n++)
     {
       int *values;
     {
       int *values;
-      unsigned int permutation_cnt;
+      unsigned int n_permutations;
       int i;
 
       int i;
 
-      values = xnmalloc (cnt, sizeof *values);
-      for (i = 0; i < cnt; i++)
+      values = xnmalloc (n, sizeof *values);
+      for (i = 0; i < n; i++)
         values[i] = i;
 
         values[i] = i;
 
-      for (permutation_cnt = 0;
-           permutation_cnt == 0 || next_permutation (values, cnt);
-           permutation_cnt++)
-        test_insert_delete (values, values, cnt);
-      check (permutation_cnt == factorial (cnt));
+      for (n_permutations = 0;
+           n_permutations == 0 || next_permutation (values, n);
+           n_permutations++)
+        test_insert_delete (values, values, n);
+      check (n_permutations == factorial (n));
 
       free (values);
     }
 
       free (values);
     }
@@ -397,29 +393,29 @@ static void
 test_insert_any_remove_reverse (void)
 {
   const int max_elems = 7;
 test_insert_any_remove_reverse (void)
 {
   const int max_elems = 7;
-  int cnt;
+  int n;
 
 
-  for (cnt = 0; cnt <= max_elems; cnt++)
+  for (n = 0; n <= max_elems; n++)
     {
       int *insertions, *deletions;
     {
       int *insertions, *deletions;
-      unsigned int permutation_cnt;
+      unsigned int n_permutations;
       int i;
 
       int i;
 
-      insertions = xnmalloc (cnt, sizeof *insertions);
-      deletions = xnmalloc (cnt, sizeof *deletions);
-      for (i = 0; i < cnt; i++)
+      insertions = xnmalloc (n, sizeof *insertions);
+      deletions = xnmalloc (n, sizeof *deletions);
+      for (i = 0; i < n; i++)
         insertions[i] = i;
 
         insertions[i] = i;
 
-      for (permutation_cnt = 0;
-           permutation_cnt == 0 || next_permutation (insertions, cnt);
-           permutation_cnt++)
+      for (n_permutations = 0;
+           n_permutations == 0 || next_permutation (insertions, n);
+           n_permutations++)
         {
         {
-          memcpy (deletions, insertions, sizeof *insertions * cnt);
-          reverse (deletions, cnt);
+          memcpy (deletions, insertions, sizeof *insertions * n);
+          reverse (deletions, n);
 
 
-          test_insert_delete (insertions, deletions, cnt);
+          test_insert_delete (insertions, deletions, n);
         }
         }
-      check (permutation_cnt == factorial (cnt));
+      check (n_permutations == factorial (n));
 
       free (insertions);
       free (deletions);
 
       free (insertions);
       free (deletions);
@@ -432,27 +428,27 @@ test_random_sequence (void)
 {
   const int max_elems = 64;
   const int max_trials = 8;
 {
   const int max_elems = 64;
   const int max_trials = 8;
-  int cnt;
+  int n;
 
 
-  for (cnt = 0; cnt <= max_elems; cnt += 2)
+  for (n = 0; n <= max_elems; n += 2)
     {
       int *insertions, *deletions;
       int trial;
       int i;
 
     {
       int *insertions, *deletions;
       int trial;
       int i;
 
-      insertions = xnmalloc (cnt, sizeof *insertions);
-      deletions = xnmalloc (cnt, sizeof *deletions);
-      for (i = 0; i < cnt; i++)
+      insertions = xnmalloc (n, sizeof *insertions);
+      deletions = xnmalloc (n, sizeof *deletions);
+      for (i = 0; i < n; i++)
         insertions[i] = i;
         insertions[i] = i;
-      for (i = 0; i < cnt; i++)
+      for (i = 0; i < n; i++)
         deletions[i] = i;
 
       for (trial = 0; trial < max_trials; trial++)
         {
         deletions[i] = i;
 
       for (trial = 0; trial < max_trials; trial++)
         {
-          random_shuffle (insertions, cnt, sizeof *insertions);
-          random_shuffle (deletions, cnt, sizeof *deletions);
+          random_shuffle (insertions, n, sizeof *insertions);
+          random_shuffle (deletions, n, sizeof *deletions);
 
 
-          test_insert_delete (insertions, deletions, cnt);
+          test_insert_delete (insertions, deletions, n);
         }
 
       free (insertions);
         }
 
       free (insertions);
@@ -644,38 +640,115 @@ test_destroy_null (void)
 \f
 /* Main program. */
 
 \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[] =
+  {
+    {
+      "insert-any-remove-any",
+      "insert any order, delete any order",
+      test_insert_any_remove_any
+    },
+    {
+      "insert-any-remove-same",
+      "insert any order, delete same order",
+      test_insert_any_remove_same
+    },
+    {
+      "insert-any-remove-reverse",
+      "insert any order, delete reverse order",
+      test_insert_any_remove_reverse
+    },
+    {
+      "random-sequence",
+      "insert and delete in random sequence",
+      test_random_sequence
+    },
+    {
+      "insert-ordered",
+      "insert in ascending order",
+      test_insert_ordered
+    },
+    {
+      "union",
+      "union",
+      test_union
+    },
+    {
+      "union-and-intersection",
+      "union and intersection",
+      test_union_and_intersection
+    },
+    {
+      "intersect",
+      "intersect",
+      test_intersect
+    },
+    {
+      "subtract",
+      "subtract",
+      test_subtract
+    },
+    {
+      "swap",
+      "swap",
+      test_swap
+    },
+    {
+      "clear",
+      "clear",
+      test_clear
+    },
+    {
+      "clone",
+      "clone",
+      test_clone
+    },
+    {
+      "destroy-null",
+      "destroying null table",
+      test_destroy_null
+    },
+  };
+
+enum { N_TESTS = sizeof tests / sizeof *tests };
 
 int
 
 int
-main (void)
-{
-  run_test (test_insert_any_remove_any, "insert any order, delete any order");
-  run_test (test_insert_any_remove_same,
-            "insert any order, delete same order");
-  run_test (test_insert_any_remove_reverse,
-            "insert any order, delete reverse order");
-  run_test (test_random_sequence, "insert and delete in random sequence");
-  run_test (test_insert_ordered, "insert in ascending order");
-  run_test (test_union, "union");
-  run_test (test_union_and_intersection, "union and intersection");
-  run_test (test_intersect, "intersect");
-  run_test (test_subtract, "subtract");
-  run_test (test_swap, "swap");
-  run_test (test_clear, "clear");
-  run_test (test_clone, "clone");
-  run_test (test_destroy_null, "destroying null table");
-
-  putchar ('\n');
-
-  free_strings ();
-
-  return 0;
+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 string set 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 ();
+            free_strings ();
+            return 0;
+          }
+
+      fprintf (stderr, "unknown test %s; use --help for help\n", argv[1]);
+      return EXIT_FAILURE;
+    }
 }
 }