1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author             Notes
8  * 2020-05-06     Phillip Johnston   the first version
9  * 2024-12-24     Meco Man           port to utest
10  */
11 
12 #include <rtklibc.h>
13 #include <utest.h>
14 
TC_rt_memcmp_str(void)15 static void TC_rt_memcmp_str(void)
16 {
17     const char* s = "abc 123";
18 
19     uassert_int_equal(rt_memcmp("abc", "abc", 4), 0);
20     uassert_int_equal(rt_memcmp(s, "abc", 3), 0);
21     uassert_int_equal(rt_memcmp("abc", s, 3), 0);
22 
23     /* The following tests intentionally use a length > 3 */
24     /* To test what rt_memcmp does in such a situation */
25     uassert_value_greater(rt_memcmp(s, "abc", 6), 0);
26     uassert_value_less(rt_memcmp("abc", s, 6), 0);
27 }
28 
TC_rt_memcmp_int_array(void)29 static void TC_rt_memcmp_int_array(void)
30 {
31     int arr1[] = {1, 2, 3, 4, 5};
32     int arr2[] = {1, 2, 3, 4, 5};
33     int arr3[] = {1, 2, 3, 4, 6};
34 
35     uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0);
36     uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0);
37     uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0);
38 }
39 
TC_rt_memcmp_float_array(void)40 static void TC_rt_memcmp_float_array(void)
41 {
42     float arr1[] = {1.0f, 2.0f, 3.0f};
43     float arr2[] = {1.0f, 2.0f, 3.0f};
44     float arr3[] = {1.0f, 2.0f, 3.1f};
45 
46     uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0);
47     uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0);
48     uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0);
49 }
50 
51 typedef struct {
52     int id;
53     float value;
54 } Item;
55 
TC_rt_memcmp_struct_array(void)56 static void TC_rt_memcmp_struct_array(void)
57 {
58     Item arr1[] = {{1, 1.0f}, {2, 2.0f}};
59     Item arr2[] = {{1, 1.0f}, {2, 2.0f}};
60     Item arr3[] = {{1, 1.0f}, {2, 2.1f}};
61 
62     uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0);
63     uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0);
64     uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0);
65 }
66 
67 typedef struct {
68     int id;
69     float value;
70     char name[10];
71 } MixedItem;
72 
TC_rt_memcmp_mixed_array(void)73 static void TC_rt_memcmp_mixed_array(void)
74 {
75     MixedItem arr1[] = {{1, 1.0f, "item1"}, {2, 2.0f, "item2"}};
76     MixedItem arr2[] = {{1, 1.0f, "item1"}, {2, 2.0f, "item2"}};
77     MixedItem arr3[] = {{1, 1.0f, "item1"}, {2, 2.1f, "item2"}};
78 
79     uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0);
80     uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0);
81     uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0);
82 }
83 
84 typedef struct {
85     int id;
86     float score;
87 } Student;
88 
89 typedef struct {
90     Student students[3];
91     char className[10];
92 } Class;
93 
TC_rt_memcmp_nested_struct_array(void)94 static void TC_rt_memcmp_nested_struct_array(void)
95 {
96     Class class1 = {
97         .students = {{1, 90.5}, {2, 85.0}, {3, 92.0}},
98         .className = "ClassA"
99     };
100 
101     Class class2 = {
102         .students = {{1, 90.5}, {2, 85.0}, {3, 92.0}},
103         .className = "ClassA"
104     };
105 
106     Class class3 = {
107         .students = {{1, 90.5}, {2, 85.1}, {3, 92.0}},
108         .className = "ClassA"
109     };
110 
111     uassert_int_equal(rt_memcmp(&class1, &class2, sizeof(Class)), 0);
112     uassert_int_not_equal(rt_memcmp(&class1, &class3, sizeof(Class)), 0);
113 }
114 
TC_rt_memcmp_partial_match(void)115 static void TC_rt_memcmp_partial_match(void)
116 {
117     char arr1[] = "abcdefghijklmnopqrstuvwxyz";
118     char arr2[] = "abcdefghijklmxyznopqrstuvw";
119 
120     uassert_int_equal(rt_memcmp(arr1, arr2, 13), 0);
121     uassert_int_not_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0);
122 }
123 
124 #define LARGE_ARRAY_SIZE 500
125 
TC_rt_memcmp_large_array(void)126 static void TC_rt_memcmp_large_array(void)
127 {
128     int *arr1 = rt_calloc(LARGE_ARRAY_SIZE, sizeof(int));
129     int *arr2 = rt_calloc(LARGE_ARRAY_SIZE, sizeof(int));
130 
131     uassert_not_null(arr1);
132     uassert_not_null(arr2);
133 
134     for (int i = 0; i < LARGE_ARRAY_SIZE; i++) {
135         arr1[i] = i;
136         arr2[i] = i;
137     }
138 
139     uassert_int_equal(rt_memcmp(arr1, arr2, LARGE_ARRAY_SIZE * sizeof(int)), 0);
140     arr2[LARGE_ARRAY_SIZE - 1] = LARGE_ARRAY_SIZE;
141 
142     uassert_value_less(rt_memcmp(arr1, arr2, LARGE_ARRAY_SIZE * sizeof(int)), 0);
143     uassert_value_greater(rt_memcmp(arr2, arr1, LARGE_ARRAY_SIZE * sizeof(int)), 0);
144 
145     rt_free(arr1);
146     rt_free(arr2);
147 }
148 
utest_do_tc(void)149 static void utest_do_tc(void)
150 {
151     UTEST_UNIT_RUN(TC_rt_memcmp_str);
152     UTEST_UNIT_RUN(TC_rt_memcmp_int_array);
153     UTEST_UNIT_RUN(TC_rt_memcmp_float_array);
154     UTEST_UNIT_RUN(TC_rt_memcmp_struct_array);
155     UTEST_UNIT_RUN(TC_rt_memcmp_mixed_array);
156     UTEST_UNIT_RUN(TC_rt_memcmp_nested_struct_array);
157     UTEST_UNIT_RUN(TC_rt_memcmp_partial_match);
158     UTEST_UNIT_RUN(TC_rt_memcmp_large_array);
159 }
160 
161 UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_memcmp", RT_NULL, RT_NULL, 1000);
162