1 #include "config.h"
2
3 #include <string.h>
4 #include <stdlib.h>
5 #include <limits.h>
6 #include <float.h>
7 #include <math.h>
8
9 #include <ccan/array_size/array_size.h>
10
11 #include <ccan/order/order.h>
12 #include <ccan/tap/tap.h>
13
14 #include <ccan/asort/asort.h>
15
16 #define QSORT_SCALAR(t, oname, ...) \
17 { \
18 t arr0[] = { __VA_ARGS__ }; \
19 const int num = ARRAY_SIZE(arr0); \
20 t arr1[num], arr2[num]; \
21 int i; \
22 \
23 /* Intialize arr1 in reverse order */ \
24 for (i = 0; i < num; i++) \
25 arr1[i] = arr0[num-i-1]; \
26 \
27 memcpy(arr2, arr1, sizeof(arr1)); \
28 qsort(arr2, num, sizeof(t), order_##oname##_noctx); \
29 ok(memcmp(arr2, arr0, sizeof(arr0)) == 0, \
30 "qsort order_%s_noctx", #oname); \
31 \
32 qsort(arr2, num, sizeof(t), order_##oname##_reverse_noctx); \
33 ok(memcmp(arr2, arr1, sizeof(arr1)) == 0, \
34 "qsort order_%s_reverse_noctx", #oname); \
35 }
36
37 #define ASORT_SCALAR(t, oname, ...) \
38 { \
39 t arr0[] = { __VA_ARGS__ }; \
40 const int num = ARRAY_SIZE(arr0); \
41 t arr1[num], arr2[num]; \
42 int i; \
43 \
44 /* Intialize arr1 in reverse order */ \
45 for (i = 0; i < num; i++) \
46 arr1[i] = arr0[num-i-1]; \
47 \
48 memcpy(arr2, arr1, sizeof(arr1)); \
49 asort(arr2, num, order_##oname, NULL); \
50 ok(memcmp(arr2, arr0, sizeof(arr0)) == 0, \
51 "asort order_%s", #oname); \
52 \
53 asort(arr2, num, order_##oname##_reverse, NULL); \
54 ok(memcmp(arr2, arr1, sizeof(arr1)) == 0, \
55 "asort order_%s_reverse", #oname); \
56 }
57
58 #define ASORT_STRUCT_BY_SCALAR(t, oname, ...) \
59 { \
60 t arrbase[] = { __VA_ARGS__ }; \
61 struct tstruct { \
62 char dummy0[5]; \
63 t val; \
64 long dummy1; \
65 }; \
66 const int num = ARRAY_SIZE(arrbase); \
67 struct tstruct arr0[num], arr1[num], arr2[num]; \
68 int i; \
69 total_order_by_field(order, oname, struct tstruct, val); \
70 total_order_by_field(rorder, oname##_reverse, \
71 struct tstruct, val); \
72 \
73 /* Set up dummy structures */ \
74 memset(arr0, 0, sizeof(arr0)); \
75 for (i = 0; i < num; i++) { \
76 arr0[i].dummy1 = i; \
77 strcpy(arr0[i].dummy0, "abc"); \
78 arr0[i].val = arrbase[i]; \
79 } \
80 \
81 /* Intialize arr1 in reverse order */ \
82 for (i = 0; i < num; i++) \
83 arr1[i] = arr0[num-i-1]; \
84 \
85 memcpy(arr2, arr1, sizeof(arr1)); \
86 asort(arr2, num, order.cb, order.ctx); \
87 ok(memcmp(arr2, arr0, sizeof(arr0)) == 0, \
88 "asort by field %s", #oname); \
89 \
90 asort(arr2, num, rorder.cb, rorder.ctx); \
91 ok(memcmp(arr2, arr1, sizeof(arr1)) == 0, \
92 "asort by field %s_reverse", #oname); \
93 }
94
95 #define TEST_SCALAR(t, oname, ...) \
96 { \
97 QSORT_SCALAR(t, oname, __VA_ARGS__); \
98 ASORT_SCALAR(t, oname, __VA_ARGS__); \
99 ASORT_STRUCT_BY_SCALAR(t, oname, __VA_ARGS__); \
100 }
101
main(void)102 int main(void)
103 {
104 /* This is how many tests you plan to run */
105 plan_tests(84);
106
107 TEST_SCALAR(int8_t, s8, -128, -4, 0, 1, 2, 88, 126, 127);
108 TEST_SCALAR(int16_t, s16, -32768, -4, 0, 1, 2, 88, 126, 32767);
109 TEST_SCALAR(int32_t, s32, -2000000000, -4, 0, 1, 2, 88, 126,
110 2000000000);
111 TEST_SCALAR(int64_t, s64, -999999999999999999LL, -2000000000, -4, 0,
112 1, 2, 88, 126, 2000000000, 999999999999999999LL);
113
114 TEST_SCALAR(uint8_t, u8, 0, 1, 2, 88, 126, 127, -10, -1);
115 TEST_SCALAR(uint16_t, u16, 0, 1, 2, 88, 126, 32767, -10, -1);
116 TEST_SCALAR(uint32_t, u32, 0, 1, 2, 88, 126, 2000000000, -10, -1);
117 TEST_SCALAR(uint64_t, u64, 0, 1, 2, 88, 126, 2000000000,
118 999999999999999999LL, -10, -1);
119
120 TEST_SCALAR(int, int, INT_MIN, -10, -1, 0, 1, 10, INT_MAX);
121 TEST_SCALAR(unsigned, uint, 0, 1, 10, INT_MAX, (unsigned)INT_MAX+1,
122 -10, -1);
123
124 TEST_SCALAR(long, long, LONG_MIN, INT_MIN, -10, -1, 0, 1, 10, INT_MAX,
125 LONG_MAX);
126 TEST_SCALAR(unsigned long, ulong, 0, 1, 10, INT_MAX,
127 (unsigned long)INT_MAX+1, LONG_MAX,
128 (unsigned long)LONG_MAX+1, -10, -1);
129
130 TEST_SCALAR(float, float, -INFINITY, -FLT_MAX, -1.0, 0.0, FLT_MIN,
131 0.1, M_E, M_PI, 5.79, FLT_MAX, INFINITY);
132 TEST_SCALAR(double, double, -INFINITY, -DBL_MAX, -FLT_MAX, -1.0, 0.0,
133 DBL_MIN, FLT_MIN, 0.1, M_E, M_PI, 5.79, FLT_MAX, DBL_MAX,
134 INFINITY);
135
136 /* This exits depending on whether all tests passed */
137 return exit_status();
138 }
139