SimpleKernel 1.17.0
Loading...
Searching...
No Matches
sk_string_test.cpp
Go to the documentation of this file.
1
5#include <gtest/gtest.h>
6
7// Rename functions to avoid conflict with standard library
8#define memcpy sk_memcpy
9#define memmove sk_memmove
10#define memset sk_memset
11#define memcmp sk_memcmp
12#define memchr sk_memchr
13#define strcpy strcpy
14#define strncpy sk_strncpy
15#define strcat sk_strcat
16#define strcmp sk_strcmp
17#define strncmp sk_strncmp
18#define strlen sk_strlen
19#define strnlen sk_strnlen
20#define strchr sk_strchr
21#define strrchr sk_strrchr
22
23// Include the source file directly to test the implementation
24// We need to use extern "C" because the included file is C
25// but the functions inside are already wrapped in extern "C" in the .h file
26// However, the .c file implementation is compiling as C++ here because the test
27// file is .cpp The .c file content: #include "sk_string.h" extern "C" {
28// ...
29// }
30// This structure is fine for C++ compilation too.
31
32#include "../../src/libc/sk_string.c"
33
34TEST(SkStringTest, Memcpy) {
35 char src[] = "hello";
36 char dest[10];
37 memcpy(dest, src, 6);
38 EXPECT_STREQ(dest, "hello");
39}
40
41TEST(SkStringTest, Memmove) {
42 char str[] = "memory move test";
43 // Overlap: dest > src
44 memmove(str + 7, str, 6); // "memory " -> "memory " at pos 7
45 // "memory memoryest"
46 EXPECT_STREQ(str, "memory memoryest");
47
48 char str2[] = "memory move test";
49 // Overlap: dest < src
50 memmove(str2, str2 + 7, 4); // "move" -> starts at 0
51 // "move ry move test"
52 EXPECT_EQ(str2[0], 'm');
53 EXPECT_EQ(str2[1], 'o');
54 EXPECT_EQ(str2[2], 'v');
55 EXPECT_EQ(str2[3], 'e');
56}
57
58TEST(SkStringTest, Memset) {
59 char buffer[10];
60 memset(buffer, 'A', 5);
61 for (int i = 0; i < 5; ++i) {
62 EXPECT_EQ(buffer[i], 'A');
63 }
64}
65
66TEST(SkStringTest, Memcmp) {
67 char s1[] = "abc";
68 char s2[] = "abc";
69 char s3[] = "abd";
70 char s4[] = "aba";
71
72 EXPECT_EQ(memcmp(s1, s2, 3), 0);
73 EXPECT_LT(memcmp(s1, s3, 3), 0); // 'c' < 'd' -> 99 - 100 < 0
74 EXPECT_GT(memcmp(s1, s4, 3), 0); // 'c' > 'a'
75}
76
77TEST(SkStringTest, Memchr) {
78 char s[] = "hello world";
79 const void* res = memchr(s, 'w', 11);
80 EXPECT_EQ(static_cast<const char*>(res), &s[6]);
81
82 res = memchr(s, 'z', 11);
83 EXPECT_EQ(res, nullptr);
84}
85
86TEST(SkStringTest, Strcpy) {
87 char src[] = "test";
88 char dest[10];
89 strcpy(dest, src);
90 EXPECT_STREQ(dest, "test");
91}
92
93TEST(SkStringTest, Strncpy) {
94 char src[] = "test string";
95 char dest[20];
96
97 // Normal case
98 sk_strncpy(dest, src, 4);
99 // manual null termination check if expected,
100 // but standard strncpy does NOT null terminate if limit reached?
101 // sk_string.c implementation should be checked.
102 // Usually strncpy pads with nulls if n > src_len, and does NOT null terminate
103 // if n <= src_len
104
105 // Let's verify behavior with simpler test first
106 memset(dest, 0, 20);
107 sk_strncpy(dest, "abc", 5);
108 EXPECT_STREQ(dest, "abc");
109
110 sk_strncpy(dest, "abcdef", 3);
111 EXPECT_EQ(dest[0], 'a');
112 EXPECT_EQ(dest[1], 'b');
113 EXPECT_EQ(dest[2], 'c');
114 // dest[3] should remain 0 from memset
115 EXPECT_EQ(dest[3], '\0');
116}
117
118TEST(SkStringTest, Strcat) {
119 char dest[20] = "hello";
120 sk_strcat(dest, " world");
121 EXPECT_STREQ(dest, "hello world");
122}
123
124TEST(SkStringTest, Strcmp) {
125 EXPECT_EQ(strcmp("abc", "abc"), 0);
126 EXPECT_LT(strcmp("abc", "abd"), 0);
127 EXPECT_GT(strcmp("abc", "aba"), 0);
128 EXPECT_LT(strcmp("abc", "abcd"), 0);
129}
130
131TEST(SkStringTest, Strncmp) {
132 EXPECT_EQ(sk_strncmp("abc", "abd", 2), 0); // "ab" vs "ab"
133 EXPECT_LT(sk_strncmp("abc", "abd", 3), 0);
134}
135
136TEST(SkStringTest, Strlen) {
137 EXPECT_EQ(strlen("hello"), 5);
138 EXPECT_EQ(strlen(""), 0);
139}
140
141TEST(SkStringTest, Strnlen) {
142 EXPECT_EQ(strnlen("hello", 10), 5);
143 EXPECT_EQ(strnlen("hello", 3), 3);
144}
145
146TEST(SkStringTest, Strchr) {
147 char s[] = "hello";
148 EXPECT_STREQ(strchr(s, 'e'), "ello");
149 EXPECT_EQ(strchr(s, 'z'), nullptr);
150 EXPECT_STREQ(strchr(s, 'l'), "llo"); // first 'l'
151}
152
153TEST(SkStringTest, Strrchr) {
154 char s[] = "hello";
155 EXPECT_STREQ(strrchr(s, 'l'), "lo"); // last 'l'
156 EXPECT_EQ(strrchr(s, 'z'), nullptr);
157}
158
159// 边界条件测试
160TEST(SkStringTest, MemcpyEdgeCases) {
161 char src[] = "test";
162 char dest[10];
163
164 // 零长度复制
165 memcpy(dest, src, 0);
166
167 // 单字节复制
168 memcpy(dest, src, 1);
169 EXPECT_EQ(dest[0], 't');
170}
171
172TEST(SkStringTest, MemsetEdgeCases) {
173 char buffer[10];
174
175 // 零长度设置
176 memset(buffer, 'A', 0);
177
178 // 使用 0 填充
179 memset(buffer, 0, 5);
180 for (int i = 0; i < 5; ++i) {
181 EXPECT_EQ(buffer[i], 0);
182 }
183
184 // 使用负值填充 (转换为 unsigned char)
185 memset(buffer, -1, 3);
186 for (int i = 0; i < 3; ++i) {
187 EXPECT_EQ(static_cast<unsigned char>(buffer[i]), 255);
188 }
189}
190
191TEST(SkStringTest, StrcmpEdgeCases) {
192 // 空字符串比较
193 EXPECT_EQ(strcmp("", ""), 0);
194 EXPECT_LT(strcmp("", "a"), 0);
195 EXPECT_GT(strcmp("a", ""), 0);
196
197 // 一个字符串是另一个的前缀
198 EXPECT_LT(strcmp("abc", "abcd"), 0);
199 EXPECT_GT(strcmp("abcd", "abc"), 0);
200}
201
202TEST(SkStringTest, StrlenEdgeCases) {
203 // 空字符串
204 EXPECT_EQ(strlen(""), 0);
205
206 // 只有空字符
207 const char null_str[] = {'\0', 'a', 'b', '\0'};
208 EXPECT_EQ(strlen(null_str), 0);
209}
210
211TEST(SkStringTest, StrnlenEdgeCases) {
212 // n 为 0
213 EXPECT_EQ(strnlen("hello", 0), 0);
214
215 // n 大于字符串长度
216 EXPECT_EQ(strnlen("hi", 100), 2);
217
218 // n 等于字符串长度
219 EXPECT_EQ(strnlen("hello", 5), 5);
220}
221
222TEST(SkStringTest, StrchrEdgeCases) {
223 char s[] = "hello";
224
225 // 查找空字符
226 EXPECT_EQ(strchr(s, '\0'), &s[5]);
227
228 // 第一个字符
229 EXPECT_EQ(strchr(s, 'h'), s);
230}
231
232TEST(SkStringTest, StrrchrEdgeCases) {
233 char s[] = "hello";
234
235 // 查找空字符
236 EXPECT_EQ(strrchr(s, '\0'), &s[5]);
237
238 // 第一个也是最后一个
239 EXPECT_EQ(strrchr(s, 'h'), s);
240}
241
242TEST(SkStringTest, MemmoveOverlapForward) {
243 // 测试前向重叠: dest > src
244 char str[] = "1234567890";
245 memmove(str + 3, str, 5); // "12312345890"
246 EXPECT_EQ(str[3], '1');
247 EXPECT_EQ(str[4], '2');
248 EXPECT_EQ(str[5], '3');
249 EXPECT_EQ(str[6], '4');
250 EXPECT_EQ(str[7], '5');
251}
252
253TEST(SkStringTest, MemmoveOverlapBackward) {
254 // 测试后向重叠: dest < src
255 char str[] = "1234567890";
256 memmove(str, str + 3, 5); // "4567567890"
257 EXPECT_EQ(str[0], '4');
258 EXPECT_EQ(str[1], '5');
259 EXPECT_EQ(str[2], '6');
260 EXPECT_EQ(str[3], '7');
261 EXPECT_EQ(str[4], '8');
262}
263
264TEST(SkStringTest, MemmoveNoOverlap) {
265 // 无重叠
266 char src[] = "source";
267 char dest[10];
268 memmove(dest, src, 7);
269 EXPECT_STREQ(dest, "source");
270}
271
272TEST(SkStringTest, MemchrNotFound) {
273 char s[] = "hello world";
274 EXPECT_EQ(memchr(s, 'x', 11), nullptr);
275 EXPECT_EQ(memchr(s, 'z', 11), nullptr);
276}
277
278TEST(SkStringTest, MemcmpEqual) {
279 char s1[] = "test";
280 char s2[] = "test";
281 EXPECT_EQ(memcmp(s1, s2, 4), 0);
282}
283
284TEST(SkStringTest, MemcmpDifferentLengths) {
285 char s1[] = "abc";
286 char s2[] = "abcd";
287 // 只比较前3个字节
288 EXPECT_EQ(memcmp(s1, s2, 3), 0);
289}
290
291TEST(SkStringTest, StrcatMultiple) {
292 char dest[30] = "hello";
293 sk_strcat(dest, " ");
294 sk_strcat(dest, "world");
295 sk_strcat(dest, "!");
296 EXPECT_STREQ(dest, "hello world!");
297}
298
299TEST(SkStringTest, StrncpyPadding) {
300 char dest[10];
301 memset(dest, 'X', 10); // 用 'X' 填充
302
303 // 复制短字符串,应该填充空字符
304 sk_strncpy(dest, "ab", 5);
305 EXPECT_EQ(dest[0], 'a');
306 EXPECT_EQ(dest[1], 'b');
307 EXPECT_EQ(dest[2], '\0');
308 EXPECT_EQ(dest[3], '\0');
309 EXPECT_EQ(dest[4], '\0');
310}
#define memcpy
#define strcpy
#define strlen
TEST(SkStringTest, Memcpy)
#define strcmp
#define strnlen
#define memmove
#define memcmp
#define strchr
#define memset
#define strrchr
#define memchr
#define EXPECT_LT(val1, val2, msg)
#define EXPECT_GT(val1, val2, msg)
#define EXPECT_EQ(val1, val2, msg)