1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 char *array;
5 char *array_end;
6 size_t member_size;
7 
8 int
compare(const void * a1,const void * b1)9 compare (const void *a1, const void *b1)
10 {
11   const char *a = a1;
12   const char *b = b1;
13 
14   if (! (array <= a && a < array_end
15 	 && array <= b && b < array_end))
16     {
17       puts ("compare arguments not inside of the array");
18       exit (EXIT_FAILURE);
19     }
20   int ret = b[0] - a[0];
21   if (ret)
22     return ret;
23   if (member_size > 1)
24     return b[1] - a[1];
25   return 0;
26 }
27 
28 int
test(size_t nmemb,size_t size)29 test (size_t nmemb, size_t size)
30 {
31   array = malloc (nmemb * size);
32   if (array == NULL)
33     {
34       printf ("%zd x %zd: no memory", nmemb, size);
35       return 1;
36     }
37 
38   array_end = array + nmemb * size;
39   member_size = size;
40 
41   char *p;
42   size_t i;
43   size_t bias = random ();
44   for (i = 0, p = array; i < nmemb; i++, p += size)
45     {
46       p[0] = (char) (i + bias);
47       if (size > 1)
48 	p[1] = (char) ((i + bias) >> 8);
49     }
50 
51   qsort (array, nmemb, size, compare);
52 
53   for (i = 0, p = array; i < nmemb - 1; i++, p += size)
54     {
55       if (p[0] < p[size]
56 	  || (size > 1 && p[0] == p[size] && p[1] < p[size + 1]))
57 	{
58 	  printf ("%zd x %zd: failure at offset %zd\n", nmemb,
59 		  size, i);
60 	  free (array);
61 	  return 1;
62 	}
63     }
64 
65   free (array);
66   return 0;
67 }
68 
69 int
main(int argc,char ** argv)70 main (int argc, char **argv)
71 {
72   int ret = 0;
73   if (argc >= 3)
74     ret |= test (atoi (argv[1]), atoi (argv[2]));
75   else
76     {
77       ret |= test (10000, 1);
78       ret |= test (200000, 2);
79       ret |= test (2000000, 3);
80       ret |= test (2132310, 4);
81       ret |= test (1202730, 7);
82       ret |= test (1184710, 8);
83       ret |= test (272710, 12);
84       ret |= test (14170, 32);
85       ret |= test (4170, 320);
86     }
87 
88   return ret;
89 }
90