1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | |
4 | char *array; |
5 | char *array_end; |
6 | size_t member_size; |
7 | |
8 | int |
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 (s: "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 |
29 | test (size_t nmemb, size_t size) |
30 | { |
31 | array = malloc (size: nmemb * size); |
32 | if (array == NULL) |
33 | { |
34 | printf (format: "%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 (format: "%zd x %zd: failure at offset %zd\n" , nmemb, |
59 | size, i); |
60 | free (ptr: array); |
61 | return 1; |
62 | } |
63 | } |
64 | |
65 | free (ptr: array); |
66 | return 0; |
67 | } |
68 | |
69 | int |
70 | main (int argc, char **argv) |
71 | { |
72 | int ret = 0; |
73 | if (argc >= 3) |
74 | ret |= test (nmemb: atoi (argv[1]), size: atoi (argv[2])); |
75 | else |
76 | { |
77 | ret |= test (nmemb: 10000, size: 1); |
78 | ret |= test (nmemb: 200000, size: 2); |
79 | ret |= test (nmemb: 2000000, size: 3); |
80 | ret |= test (nmemb: 2132310, size: 4); |
81 | ret |= test (nmemb: 1202730, size: 7); |
82 | ret |= test (nmemb: 1184710, size: 8); |
83 | ret |= test (nmemb: 272710, size: 12); |
84 | ret |= test (nmemb: 14170, size: 32); |
85 | ret |= test (nmemb: 4170, size: 320); |
86 | } |
87 | |
88 | return ret; |
89 | } |
90 | |