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