1 /*
2 * Copyright (c) 2021 Friedt Professional Engineering Services, Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define _GNU_SOURCE
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <zephyr/ztest.h>
11
compare_ints(const void * a,const void * b)12 static int compare_ints(const void *a, const void *b)
13 {
14 int aa = *(const int *)a;
15 int bb = *(const int *)b;
16
17 return (aa > bb) - (aa < bb);
18 }
19
20 /**
21 *
22 * @brief Test qsort function
23 *
24 */
ZTEST(libc_common,test_qsort)25 ZTEST(libc_common, test_qsort)
26 {
27 {
28 int actual_int[] = { 1, 3, 2 };
29 const int expect_int[] = { 1, 3, 2 };
30
31 qsort(actual_int + 1, 0, sizeof(int), compare_ints);
32 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
33 "out-of-bounds modifications detected");
34 }
35
36 {
37 int actual_int[] = { 42 };
38 const int expect_int[] = { 42 };
39
40 qsort(actual_int, ARRAY_SIZE(actual_int), sizeof(int), compare_ints);
41 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
42 "size 1 not sorted");
43 }
44
45 {
46 int actual_int[] = { 42, -42 };
47 const int expect_int[] = { -42, 42 };
48
49 qsort(actual_int, ARRAY_SIZE(actual_int), sizeof(int), compare_ints);
50 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
51 "size 2 not sorted");
52 }
53
54 {
55 int actual_int[] = { 42, -42, 0 };
56 const int expect_int[] = { -42, 0, 42 };
57
58 qsort(actual_int, ARRAY_SIZE(actual_int), sizeof(int), compare_ints);
59 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
60 "size 3 not sorted");
61 }
62
63 {
64 int actual_int[] = { 42, -42, 0, -42 };
65 const int expect_int[] = { -42, -42, 0, 42 };
66
67 qsort(actual_int, ARRAY_SIZE(actual_int), sizeof(int), compare_ints);
68 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
69 "error handling duplicates");
70 }
71
72 {
73 /*
74 * NUMS="$(for i in `seq 0 63`; do echo -n "$(((RANDOM - 16384) % 100)), "; done)"
75 * slightly modified to ensure that there were 0, -ve and +ve duplicates
76 */
77 static int actual_int[] = {
78 1, 18, -78, 35, -67, -71, -12, -69, -60, 91, -15, -99, -33,
79 -52, 52, -4, -89, -7, 22, -52, -87, 32, -23, 30, -35, -9,
80 15, -61, 36, -49, 24, -72, -63, 77, 88, -93, 13, 49, 41,
81 35, -5, -72, -46, 64, -46, -97, -88, 90, 63, 49, 12, -58,
82 -76, 54, 75, 49, 11, 61, 42, 0, -42, 42, -42,
83 };
84
85 /* echo $(echo "$NUMS" | sed -e 's/,/\n/g' | sort -n | sed -e 's/\(.*\)/\1,\ /g') */
86 static const int expect_int[] = {
87 -99, -97, -93, -89, -88, -87, -78, -76, -72, -72, -71, -69, -67,
88 -63, -61, -60, -58, -52, -52, -49, -46, -46, -42, -42, -35, -33,
89 -23, -15, -12, -9, -7, -5, -4, 0, 1, 11, 12, 13, 15,
90 18, 22, 24, 30, 32, 35, 35, 36, 41, 42, 42, 49, 49,
91 49, 52, 54, 61, 63, 64, 75, 77, 88, 90, 91,
92 };
93
94 qsort(actual_int, ARRAY_SIZE(actual_int), sizeof(int), compare_ints);
95 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
96 "size 64 not sorted");
97 }
98
99 {
100 /*
101 * NUMS="$(for i in `seq 0 92`; do echo -n "$(((RANDOM - 16384) % 100)), "; done)"
102 * slightly modified to ensure that there were 0, -ve and +ve duplicates
103 */
104 static int actual_int[] = {
105 1, 18, -78, 35, -67, -71, -12, -69, -60, 91, -15, -99, -33, -52,
106 52, -4, -89, -7, 22, -52, -87, 32, -23, 30, -35, -9, 15, -61,
107 36, -49, 24, -72, -63, 77, 88, -93, 13, 49, 41, 35, -5, -72,
108 -46, 64, -46, -97, 90, 63, 49, 12, -58, -76, 54, 75, 49, 11,
109 61, -45, 92, 7, 74, -3, -9, 96, 83, 33, 15, -40, -84, -57,
110 40, -93, -27, 38, 24, 41, -70, -51, -88, 27, 94, 51, -11, -2,
111 -21, -70, -6, 77, 42, 0, -42, 42, -42,
112 };
113
114 /* echo $(echo "$NUMS" | sed -e 's/,/\n/g' | sort -n | sed -e 's/\(.*\)/\1,\ /g') */
115 static const int expect_int[] = {
116 -99, -97, -93, -93, -89, -88, -87, -84, -78, -76, -72, -72, -71, -70,
117 -70, -69, -67, -63, -61, -60, -58, -57, -52, -52, -51, -49, -46, -46,
118 -45, -42, -42, -40, -35, -33, -27, -23, -21, -15, -12, -11, -9, -9,
119 -7, -6, -5, -4, -3, -2, 0, 1, 7, 11, 12, 13, 15, 15,
120 18, 22, 24, 24, 27, 30, 32, 33, 35, 35, 36, 38, 40, 41,
121 41, 42, 42, 49, 49, 49, 51, 52, 54, 61, 63, 64, 74, 75,
122 77, 77, 83, 88, 90, 91, 92, 94, 96,
123 };
124
125 qsort(actual_int, ARRAY_SIZE(actual_int), sizeof(int), compare_ints);
126 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int),
127 "size 93 not sorted");
128 }
129 }
130
compare_ints_with_boolp_arg(const void * a,const void * b,void * argp)131 static int compare_ints_with_boolp_arg(const void *a, const void *b, void *argp)
132 {
133 int aa = *(const int *)a;
134 int bb = *(const int *)b;
135
136 *(bool *)argp = true;
137
138 return (aa > bb) - (aa < bb);
139 }
140
ZTEST(libc_common,test_qsort_r)141 ZTEST(libc_common, test_qsort_r)
142 {
143 bool arg = false;
144
145 const int expect_int[] = { 1, 5, 7 };
146 int actual_int[] = { 1, 7, 5 };
147
148 qsort_r(actual_int, ARRAY_SIZE(actual_int), sizeof(actual_int[0]),
149 compare_ints_with_boolp_arg, &arg);
150
151 zassert_mem_equal(actual_int, expect_int, sizeof(expect_int), "array not sorted");
152 zassert_true(arg, "arg not modified");
153 }
154