root/maint/gnulib/tests/test-linkedhash_set.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cmp_objects_in_array
  2. check_equals
  3. check_all
  4. string_equals
  5. string_hashcode
  6. main

   1 /* Test of set data type implementation.
   2    Copyright (C) 2006-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2018.
   4 
   5    This program is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU General Public License as published by
   7    the Free Software Foundation; either version 3 of the License, or
   8    (at your option) any later version.
   9 
  10    This program is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU General Public License for more details.
  14 
  15    You should have received a copy of the GNU General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 #include <config.h>
  19 
  20 #include "gl_linkedhash_set.h"
  21 
  22 #include <stdlib.h>
  23 #include <string.h>
  24 
  25 #include "gl_array_set.h"
  26 #include "xalloc.h"
  27 #include "macros.h"
  28 
  29 static const char *objects[30] =
  30   {
  31     "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
  32     "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "<", ">", "[", "]"
  33   };
  34 
  35 #define RANDOM(n) (rand () % (n))
  36 #define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
  37 
  38 static int
  39 cmp_objects_in_array (const void *objptr1, const void *objptr2)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41   const void *obj1 = *(const void * const *)objptr1;
  42   const void *obj2 = *(const void * const *)objptr2;
  43   return strcmp ((const char *) obj1, (const char *) obj2);
  44 }
  45 
  46 static void
  47 check_equals (gl_set_t set1, gl_set_t set2)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49   size_t n = gl_set_size (set1);
  50   const void **elements_of_set1 = XNMALLOC (n, const void *);
  51   const void **elements_of_set2 = XNMALLOC (n, const void *);
  52 
  53   gl_set_iterator_t iter1;
  54   gl_set_iterator_t iter2;
  55   const void *elt1;
  56   const void *elt2;
  57   size_t i;
  58 
  59   iter1 = gl_set_iterator (set1);
  60   iter2 = gl_set_iterator (set2);
  61   for (i = 0; i < n; i++)
  62     {
  63       ASSERT (gl_set_iterator_next (&iter1, &elt1));
  64       ASSERT (gl_set_iterator_next (&iter2, &elt2));
  65       elements_of_set1[i] = elt1;
  66       elements_of_set2[i] = elt2;
  67     }
  68   ASSERT (!gl_set_iterator_next (&iter1, &elt1));
  69   ASSERT (!gl_set_iterator_next (&iter2, &elt2));
  70   gl_set_iterator_free (&iter1);
  71   gl_set_iterator_free (&iter2);
  72 
  73   if (n > 0)
  74     {
  75       qsort (elements_of_set1, n, sizeof (const void *), cmp_objects_in_array);
  76       qsort (elements_of_set2, n, sizeof (const void *), cmp_objects_in_array);
  77     }
  78   for (i = 0; i < n; i++)
  79     ASSERT (elements_of_set1[i] == elements_of_set2[i]);
  80   free (elements_of_set2);
  81   free (elements_of_set1);
  82 }
  83 
  84 static void
  85 check_all (gl_set_t set1, gl_set_t set2)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87   check_equals (set1, set2);
  88 }
  89 
  90 static bool
  91 string_equals (const void *elt1, const void *elt2)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   return strcmp ((const char *) elt1, (const char *) elt2) == 0;
  94 }
  95 
  96 static size_t
  97 string_hashcode (const void *elt)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99   size_t hashcode = 0;
 100   const char *s;
 101   for (s = (const char *) elt; *s != '\0'; s++)
 102     hashcode += (unsigned char) *s;
 103   return hashcode;
 104 }
 105 
 106 int
 107 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109   gl_set_t set1, set2;
 110 
 111   /* Allow the user to provide a non-default random seed on the command line.  */
 112   if (argc > 1)
 113     srand (atoi (argv[1]));
 114 
 115   {
 116     size_t initial_size = RANDOM (20);
 117     size_t i;
 118     unsigned int repeat;
 119 
 120     /* Create set1.  */
 121     set1 = gl_set_nx_create_empty (GL_ARRAY_SET, string_equals, string_hashcode, NULL);
 122     ASSERT (set1 != NULL);
 123 
 124     /* Create set2.  */
 125     set2 = gl_set_nx_create_empty (GL_LINKEDHASH_SET, string_equals, string_hashcode, NULL);
 126     ASSERT (set2 != NULL);
 127 
 128     check_all (set1, set2);
 129 
 130     /* Initialize them.  */
 131     for (i = 0; i < initial_size; i++)
 132       {
 133         const char *obj = RANDOM_OBJECT ();
 134         ASSERT (gl_set_nx_add (set1, obj) == gl_set_nx_add (set2, obj));
 135         check_all (set1, set2);
 136       }
 137 
 138     for (repeat = 0; repeat < 100000; repeat++)
 139       {
 140         unsigned int operation = RANDOM (3);
 141         switch (operation)
 142           {
 143           case 0:
 144             {
 145               const char *obj = RANDOM_OBJECT ();
 146               ASSERT (gl_set_search (set1, obj) == gl_set_search (set2, obj));
 147             }
 148             break;
 149           case 1:
 150             {
 151               const char *obj = RANDOM_OBJECT ();
 152               ASSERT (gl_set_nx_add (set1, obj) == gl_set_nx_add (set2, obj));
 153             }
 154             break;
 155           case 2:
 156             {
 157               const char *obj = RANDOM_OBJECT ();
 158               ASSERT (gl_set_remove (set1, obj) == gl_set_remove (set2, obj));
 159             }
 160             break;
 161           }
 162         check_all (set1, set2);
 163       }
 164 
 165     gl_set_free (set1);
 166     gl_set_free (set2);
 167   }
 168 
 169   return 0;
 170 }

/* [previous][next][first][last][top][bottom][index][help] */