1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * @file test access to the minimal C libraries
9  *
10  * This module verifies that the various minimal C libraries can be used.
11  *
12  * IMPORTANT: The module only ensures that each supported library is present,
13  * and that a bare minimum of its functionality is operating correctly. It does
14  * NOT guarantee that ALL standards-defined functionality is present, nor does
15  * it guarantee that ALL functionality provided is working correctly.
16  */
17 
18 #include <zephyr.h>
19 #include <sys/__assert.h>
20 #include <ztest.h>
21 
22 #include <limits.h>
23 #include <sys/types.h>
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <ctype.h>
33 #include <time.h>
34 #include <ztest_error_hook.h>
35 
36 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
37 #define LIST_LEN 2
38 
39 static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
40 static struct k_thread tdata;
41 
42 /* Recent GCC's are issuing a warning for the truncated strncpy()
43  * below (the static source string is longer than the locally-defined
44  * destination array).  That's exactly the case we're testing, so turn
45  * it off.
46  */
47 #if defined(__GNUC__) && __GNUC__ >= 8
48 #pragma GCC diagnostic ignored "-Wstringop-truncation"
49 #endif
50 
51 /*
52  * variables used during limits library testing; must be marked as "volatile"
53  * to prevent compiler from computing results at compile time
54  */
55 
56 volatile long long_max = LONG_MAX;
57 volatile long long_one = 1L;
58 
59 /**
60  *
61  * @brief Test implementation-defined constants library
62  * @defgroup libc_api
63  * @ingroup all_tests
64  * @{
65  *
66  */
67 
test_limits(void)68 void test_limits(void)
69 {
70 
71 	zassert_true((long_max + long_one == LONG_MIN), NULL);
72 }
73 
foobar(void)74 static ssize_t foobar(void)
75 {
76 	return -1;
77 }
78 
test_ssize_t(void)79 void test_ssize_t(void)
80 {
81 	zassert_true(foobar() < 0, NULL);
82 }
83 
84 /**
85  *
86  * @brief Test boolean types and values library
87  *
88  */
test_stdbool(void)89 void test_stdbool(void)
90 {
91 
92 	zassert_true((true == 1), "true value");
93 	zassert_true((false == 0), "false value");
94 }
95 
96 /*
97  * variables used during stddef library testing; must be marked as "volatile"
98  * to prevent compiler from computing results at compile time
99  */
100 
101 volatile long long_variable;
102 volatile size_t size_of_long_variable = sizeof(long_variable);
103 
104 /**
105  *
106  * @brief Test standard type definitions library
107  *
108  */
test_stddef(void)109 void test_stddef(void)
110 {
111 #ifdef CONFIG_64BIT
112 	zassert_true((size_of_long_variable == 8), "sizeof");
113 #else
114 	zassert_true((size_of_long_variable == 4), "sizeof");
115 #endif
116 }
117 
118 /*
119  * variables used during stdint library testing; must be marked as "volatile"
120  * to prevent compiler from computing results at compile time
121  */
122 
123 volatile uint8_t unsigned_byte = 0xff;
124 volatile uint32_t unsigned_int = 0xffffff00;
125 
126 /**
127  *
128  * @brief Test integer types library
129  *
130  */
test_stdint(void)131 void test_stdint(void)
132 {
133 	zassert_true((unsigned_int + unsigned_byte + 1u == 0U), NULL);
134 
135 #if (UINT8_C(1) == 1)			\
136 	&& (INT8_C(-1) == -1)		\
137 	&& (UINT16_C(2) == 2)		\
138 	&& (INT16_C(-2) == -2)		\
139 	&& (UINT32_C(4) == 4)		\
140 	&& (INT32_C(-4) == -4)		\
141 	&& (UINT64_C(8) == 8)		\
142 	&& (INT64_C(-8) == -8)		\
143 	&& (UINTMAX_C(11) == 11)	\
144 	&& (INTMAX_C(-11) == -11)
145 	zassert_true(true, NULL);
146 #else
147 	zassert_true(false, "const int expr values ...");
148 #endif
149 }
150 
151 /*
152  * variables used during string library testing
153  */
154 
155 #define BUFSIZE 10
156 
157 char buffer[BUFSIZE];
158 
159 /**
160  *
161  * @brief Test string memset
162  *
163  */
test_memset(void)164 void test_memset(void)
165 {
166 	int i, ret;
167 	const char set = 'a';
168 	int size = 0;
169 
170 	memset(buffer, 0, 10);
171 	for (i = 0; i < 10; i++) {
172 		memset(buffer + i, set, size);
173 		memset(buffer + i, set, 1);
174 		ret = memcmp(buffer + i, &set, 1);
175 		zassert_true((ret == 0), "memset buffer a failed");
176 	}
177 }
178 
179 /**
180  *
181  * @brief Test string length function
182  *
183  * @see strlen(), strnlen().
184  *
185  */
test_strlen(void)186 void test_strlen(void)
187 {
188 	(void)memset(buffer, '\0', BUFSIZE);
189 	(void)memset(buffer, 'b', 5); /* 5 is BUFSIZE / 2 */
190 	zassert_equal(strlen(buffer), 5, "strlen failed");
191 
192 	zassert_equal(strnlen(buffer, 3), 3, "strnlen failed");
193 	zassert_equal(strnlen(buffer, BUFSIZE), 5, "strnlen failed");
194 }
195 
196 /**
197  *
198  * @brief Test string compare function
199  *
200  * @see strcmp(), strncasecmp().
201  *
202  */
test_strcmp(void)203 void test_strcmp(void)
204 {
205 	strcpy(buffer, "eeeee");
206 	char test = 0;
207 
208 	zassert_true((strcmp(buffer, "fffff") < 0), "strcmp less ...");
209 	zassert_true((strcmp(buffer, "eeeee") == 0), "strcmp equal ...");
210 	zassert_true((strcmp(buffer, "ddddd") > 0), "strcmp greater ...");
211 
212 	zassert_true((strncasecmp(buffer, "FFFFF", 3) < 0), "strncasecmp less ...");
213 	zassert_true((strncasecmp(buffer, "DDDDD", 3) > 0), "strncasecmp equal ...");
214 	zassert_true((strncasecmp(buffer, "EEEEE", 3) == 0), "strncasecmp greater ...");
215 	zassert_true((strncasecmp(&test, &test, 1) == 0), "strncasecmp failed");
216 }
217 
218 /**
219  *
220  * @brief Test string N compare function
221  *
222  * @see strncmp().
223  */
test_strncmp(void)224 void test_strncmp(void)
225 {
226 	static const char pattern[] = "eeeeeeeeeeee";
227 
228 	/* Note we don't want to count the final \0 that sizeof will */
229 	__ASSERT_NO_MSG(sizeof(pattern) - 1 > BUFSIZE);
230 	memcpy(buffer, pattern, BUFSIZE);
231 
232 	zassert_true((strncmp(buffer, "fffff", 0) == 0), "strncmp 0");
233 	zassert_true((strncmp(buffer, "eeeff", 3) == 0), "strncmp 3");
234 	zassert_true((strncmp(buffer, "eeeff", 4) != 0), "strncmp 4");
235 	zassert_true((strncmp(buffer, "eeeeeeeeeeeff", BUFSIZE) == 0),
236 		     "strncmp 10");
237 
238 	/* test compare the same strings */
239 	buffer[BUFSIZE - 1] = '\0';
240 	zassert_true((strncmp(buffer, buffer, BUFSIZE) == 0),
241 				 "strncmp 10 with \0");
242 }
243 
244 
245 /**
246  *
247  * @brief Test string copy function
248  *
249  * @see strcpy().
250  */
test_strcpy(void)251 void test_strcpy(void)
252 {
253 	(void)memset(buffer, '\0', BUFSIZE);
254 	strcpy(buffer, "10 chars!\0");
255 
256 	zassert_true((strcmp(buffer, "10 chars!\0") == 0), "strcpy");
257 }
258 
259 /**
260  *
261  * @brief Test string N copy function
262  *
263  * @see strncpy().
264  */
test_strncpy(void)265 void test_strncpy(void)
266 {
267 	int ret;
268 
269 	(void)memset(buffer, '\0', BUFSIZE);
270 	strncpy(buffer, "This is over 10 characters", BUFSIZE);
271 
272 	/* Purposely different values */
273 	ret = strncmp(buffer, "This is over 20 characters", BUFSIZE);
274 	zassert_true((ret == 0), "strncpy");
275 
276 }
277 
278 /**
279  *
280  * @brief Test string scanning function
281  *
282  * @see strchr().
283  */
test_strchr(void)284 void test_strchr(void)
285 {
286 	char *rs = NULL;
287 	int ret;
288 
289 	(void)memset(buffer, '\0', BUFSIZE);
290 	strncpy(buffer, "Copy 10", BUFSIZE);
291 
292 	rs = strchr(buffer, '1');
293 
294 	zassert_not_null(rs, "strchr");
295 
296 
297 	ret = strncmp(rs, "10", 2);
298 	zassert_true((ret == 0), "strchr");
299 
300 }
301 
302 /**
303  *
304  * @brief Test string prefix match functions
305  *
306  * @see strspn(),strcspn().
307  */
test_strxspn(void)308 void test_strxspn(void)
309 {
310 	const char *empty = "";
311 	const char *cset = "abc";
312 
313 	zassert_true(strspn("", empty) == 0U, "strspn empty empty");
314 	zassert_true(strcspn("", empty) == 0U, "strcspn empty empty");
315 
316 	zassert_true(strspn("abde", cset) == 2U, "strspn match");
317 	zassert_true(strcspn("abde", cset) == 0U, "strcspn nomatch");
318 
319 	zassert_true(strspn("da", cset) == 0U, "strspn nomatch");
320 	zassert_true(strcspn("da", cset) == 1U, "strcspn match");
321 
322 	zassert_true(strspn("abac", cset) == 4U, "strspn all");
323 	zassert_true(strcspn("defg", cset) == 4U, "strcspn all");
324 }
325 
326 /**
327  *
328  * @brief Test memory comparison function
329  *
330  * @see memcmp()
331  */
test_memcmp(void)332 void test_memcmp(void)
333 {
334 	int ret;
335 	unsigned char m1[] = "a\0$def";
336 	unsigned char m2[] = "a\0$dhj";
337 
338 
339 	ret = memcmp(m1, m2, 4);
340 	zassert_true((ret == 0), "memcmp four characters failed");
341 
342 	ret = memcmp(m1, m2, 5);
343 	zassert_true((ret != 0), "memcmp five characters failed");
344 
345 	ret = memcmp(m1, m2, 0);
346 	zassert_true((ret == 0), "memcmp zero character failed");
347 
348 	ret = memcmp(m1, m2, sizeof(m2));
349 	zassert_true((ret != 0), "memcmp 2 block of memory failed");
350 }
351 
352 /**
353  *
354  * @brief Test binary search function
355  *
356  * @see bsearch()
357  */
cmp_func(const void * a,const void * b)358 int cmp_func(const void *a, const void *b)
359 {
360 	return (*(int *)a - *(int *)b);
361 }
362 
test_bsearch(void)363 void test_bsearch(void)
364 {
365 	void *result = NULL;
366 	int arr[5] = { 2, 5, 20, 50, 60 };
367 	size_t size = ARRAY_SIZE(arr);
368 	int key = 30;
369 
370 	result = (int *)bsearch(&key, arr, size, sizeof(int), cmp_func);
371 	zassert_is_null(result, "bsearch -key not found");
372 
373 	key = 60;
374 	result = (int *)bsearch(&key, arr, size, sizeof(int), cmp_func);
375 	zassert_not_null(result, "bsearch -key found");
376 }
377 
378 /**
379  *
380  * @brief Test abs function
381  *
382  * @see abs()
383  */
test_abs(void)384 void test_abs(void)
385 {
386 	int val = -5, value = 5;
387 
388 	zassert_equal(abs(val), 5, "abs -5");
389 	zassert_equal(abs(value), 5, "abs 5");
390 }
391 
392 /**
393  *
394  * @brief Test atoi function
395  *
396  * @see atoi()
397  */
test_atoi(void)398 void test_atoi(void)
399 {
400 	zassert_equal(atoi("123"), 123, "atoi error");
401 	zassert_equal(atoi("2c5"), 2, "atoi error");
402 	zassert_equal(atoi("acd"), 0, "atoi error");
403 	zassert_equal(atoi(" "), 0, "atoi error");
404 	zassert_equal(atoi(""), 0, "atoi error");
405 	zassert_equal(atoi("3-4e"), 3, "atoi error");
406 	zassert_equal(atoi("8+1c"), 8, "atoi error");
407 	zassert_equal(atoi("+3"), 3, "atoi error");
408 	zassert_equal(atoi("-1"), -1, "atoi error");
409 }
410 
411 /**
412  *
413  * @brief Test value type
414  *
415  * @details This function check the char type,
416  * and verify the return value.
417  *
418  * @see isalnum(), isalpha(), isdigit(), isgraph(),
419  * isprint(), isspace(), isupper(), isxdigit().
420  *
421  */
test_checktype(void)422 void test_checktype(void)
423 {
424 	static const char exp_alnum[] =
425 		"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
426 	static const char exp_alpha[] =
427 		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
428 	static const char exp_digit[] = "0123456789";
429 	static const char exp_graph[] =
430 		"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
431 	static const char exp_print[] =
432 		" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
433 	static const char exp_space[] = {"\x9\xa\xb\xc\xd\x20"};
434 
435 	static const char exp_upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
436 	static const char exp_xdigit[] = "0123456789ABCDEFabcdef";
437 	char buf[128];
438 	char *ptr = buf;
439 
440 	for (int i = 0; i < 128; i++) {
441 		if (isalnum(i))
442 			*ptr++ = i;
443 	}
444 	*ptr = '\0';
445 	zassert_equal(strcmp(buf, exp_alnum), 0, "isalnum error");
446 
447 	ptr = buf;
448 	for (int i = 0; i < 128; i++) {
449 		if (isalpha(i))
450 			*ptr++ = i;
451 	}
452 	*ptr = '\0';
453 	zassert_equal(strcmp(buf, exp_alpha), 0, "isalpha error");
454 
455 	ptr = buf;
456 	for (int i = 0; i < 128; i++) {
457 		if (isdigit(i))
458 			*ptr++ = i;
459 	}
460 	*ptr = '\0';
461 	zassert_equal(strcmp(buf, exp_digit), 0, "isdigit error");
462 
463 	ptr = buf;
464 	for (int i = 0; i < 128; i++) {
465 		if (isgraph(i))
466 			*ptr++ = i;
467 	}
468 	*ptr = '\0';
469 	zassert_equal(strcmp(buf, exp_graph), 0, "isgraph error");
470 
471 	ptr = buf;
472 	for (int i = 0; i < 128; i++) {
473 		if (isprint(i))
474 			*ptr++ = i;
475 	}
476 	*ptr = '\0';
477 	zassert_equal(strcmp(buf, exp_print), 0, "isprint error");
478 
479 	ptr = buf;
480 	for (int i = 0; i < 128; i++) {
481 		if (isupper(i))
482 			*ptr++ = i;
483 	}
484 	*ptr = '\0';
485 	zassert_equal(strcmp(buf, exp_upper), 0, "isupper error");
486 
487 	ptr = buf;
488 	for (int i = 0; i < 128; i++) {
489 		if (isspace(i))
490 			*ptr++ = i;
491 	}
492 	*ptr = '\0';
493 	zassert_equal(strcmp(buf, exp_space), 0, "isspace error");
494 
495 	ptr = buf;
496 	for (int i = 0; i < 128; i++) {
497 		if (isxdigit(i))
498 			*ptr++ = i;
499 	}
500 	*ptr = '\0';
501 	zassert_equal(strcmp(buf, exp_xdigit), 0, "isxdigit error");
502 }
503 
504 /**
505  * @brief Test memchr function
506  *
507  * @see memchr().
508  */
test_memchr(void)509 void test_memchr(void)
510 {
511 	static const char str[] = "testfunction";
512 
513 	/* verify the character inside the count scope */
514 	zassert_not_null(memchr(str, 'e', strlen(str)), "memchr serach e");
515 	zassert_not_null(memchr(str, '\0', strlen(str)+1), "memchr serach \0");
516 
517 	/* verify when the count parm is zero */
518 	zassert_is_null(memchr(str, 't', 0), "memchr count 0 error");
519 	/* verify the wanted character outside the count scope */
520 	zassert_is_null(memchr(str, '\0', strlen(str)), "memchr scope error");
521 }
522 
523 /**
524  * @brief Test memcpy operation
525  *
526  * @see memcpy().
527  */
test_memcpy(void)528 void test_memcpy(void)
529 {
530 	/* make sure the buffer is word aligned */
531 	uintptr_t mem_dest[4] = {0};
532 	uintptr_t mem_src[4] = {0};
533 	unsigned char *mem_dest_tmp = NULL;
534 	unsigned char *mem_src_tmp = NULL;
535 
536 	unsigned char *mem_dest_byte = (unsigned char *)mem_dest;
537 	unsigned char *mem_src_byte = (unsigned char *)mem_src;
538 
539 	/* initialize source buffer in bytes */
540 	for (int i = 0; i < sizeof(mem_src); i++) {
541 		mem_src_byte[i] = i;
542 	}
543 
544 	/* verify when dest in not word aligned */
545 	mem_dest_tmp = mem_dest_byte + 1;
546 	mem_src_tmp = mem_src_byte;
547 	zassert_equal(memcpy(mem_dest_tmp, mem_src_tmp, 10),
548 		mem_dest_tmp, "memcpy error");
549 	zassert_equal(memcmp(mem_dest_tmp, mem_src_tmp, 10),
550 		0, "memcpy failed");
551 
552 	/* restore the environment */
553 	memset(mem_dest_byte, '\0', sizeof(mem_dest));
554 	/* verify when dest and src are all in not word aligned */
555 	mem_dest_tmp = mem_dest_byte + sizeof(uintptr_t) - 1;
556 	mem_src_tmp = mem_src_byte + sizeof(uintptr_t) - 1;
557 	zassert_equal(memcpy(mem_dest_tmp, mem_src_tmp, 10),
558 		mem_dest_tmp, "memcpy error");
559 	zassert_equal(memcmp(mem_dest_tmp, mem_src_tmp, 10),
560 		0, "memcpy failed");
561 
562 	/* restore the environment */
563 	memset(mem_dest_byte, '\0', sizeof(mem_dest));
564 	/* verify when the copy count is zero, the copy will directly return */
565 	mem_dest_tmp = mem_dest_byte + sizeof(uintptr_t) - 1;
566 	mem_src_tmp = mem_src_byte + sizeof(uintptr_t) - 1;
567 	zassert_equal(memcpy(mem_dest_tmp, mem_src_tmp, 0),
568 		mem_dest_tmp, "memcpy error");
569 	zassert_not_equal(memcmp(mem_dest_tmp, mem_src_tmp, 10),
570 		0, "memcpy failed");
571 }
572 
573 /**
574  * @brief Test memmove operation
575  *
576  * @see memmove().
577  */
test_memmove(void)578 void test_memmove(void)
579 {
580 	char move_buffer[6] = "12123";
581 	char move_new[6] = {0};
582 	static const char move_overlap[6] = "12121";
583 
584 	/* verify <src> buffer overlaps with the start of the <dest> buffer */
585 	zassert_equal(memmove(move_buffer + 2, move_buffer, 3), move_buffer + 2,
586 		     "memmove error");
587 	zassert_equal(memcmp(move_overlap, move_buffer, sizeof(move_buffer)), 0,
588 		     "memmove failed");
589 
590 	/* verify the buffer is not overlap, then forward-copy */
591 	zassert_equal(memmove(move_new, move_buffer, sizeof(move_buffer)), move_new,
592 		     "memmove error");
593 	zassert_equal(memcmp(move_new, move_buffer, sizeof(move_buffer)), 0,
594 		     "memmove failed");
595 }
596 
597 /**
598  *
599  * @brief test str operate functions
600  *
601  * @see strcat(), strcspn(), strncat().
602  *
603  */
test_str_operate(void)604 void test_str_operate(void)
605 {
606 	char str1[10] = "aabbcc", ncat[10] = "ddee";
607 	char *str2 = "b";
608 	char *str3 = "d";
609 	int ret;
610 	char *ptr;
611 
612 	zassert_not_null(strcat(str1, str3), "strcat false");
613 	zassert_equal(strcmp(str1, "aabbccd"), 0, "test strcat failed");
614 
615 	ret = strcspn(str1, str2);
616 	zassert_equal(ret, 2, "strcspn failed");
617 	ret = strcspn(str1, str3);
618 	zassert_equal(ret, 6, "strcspn not found str");
619 
620 	zassert_true(strncat(ncat, str1, 2), "strncat failed");
621 	zassert_not_null(strncat(str1, str3, 2), "strncat failed");
622 	zassert_not_null(strncat(str1, str3, 1), "strncat failed");
623 	zassert_equal(strcmp(ncat, "ddeeaa"), 0, "strncat failed");
624 
625 	zassert_is_null(strrchr(ncat, 'z'),
626 		       "strrchr not found this word. failed");
627 	ptr = strrchr(ncat, 'e');
628 	zassert_equal(strcmp(ptr, "eaa"), 0, "strrchr failed");
629 
630 	zassert_is_null(strstr(str1, "ayz"), "strstr aabbccd with ayz failed");
631 	zassert_not_null(strstr(str1, str2), "strstr aabbccd with b succeed");
632 	zassert_not_null(strstr(str1, "bb"), "strstr aabbccd with bb succeed");
633 	zassert_not_null(strstr(str1, ""), "strstr aabbccd with \0 failed");
634 }
635 
636 /**
637  *
638  * @brief test strtol function
639  *
640  * @detail   in 32bit system:
641  *	when base is 10, [-2147483648..2147483647]
642  *		   in 64bit system:
643  *	when base is 10,
644  *    [-9,223,372,036,854,775,808..9,223,372,036,854,775,807]
645  *
646  * @see strtol().
647  *
648  */
test_strtol(void)649 void test_strtol(void)
650 {
651 	static const char buf1[] = "+10379aegi";
652 	static const char buf2[] = "   -10379aegi";
653 	static const char buf3[] = "-010379aegi";
654 	static const char buf4[] = "0x10379aegi";
655 	static const char buf5[] = "0X10379aegi";
656 	static const char buf6[] = "01037aegi";
657 	static const char buf7[] = "1037aegi";
658 	static const char buf8[] = "++1037aegi";
659 	static const char buf9[] = "A1037aegi";
660 	static const char buf10[] = "a1037aegi";
661 	static const char str_normal[] = "-1011 This stopped it";
662 	static const char str_abnormal[] = "ABCDEFGH";
663 	char *stop = NULL;
664 	long ret;
665 
666 	/* test function strtol() */
667 	ret = strtol(buf3, NULL, 8);
668 	zassert_equal(ret, -543, "strtol base = 8 failed");
669 	ret = strtol(buf1, NULL, 10);
670 	zassert_equal(ret, 10379, "strtol base = 10 failed");
671 	ret = strtol(buf2, NULL, 10);
672 	zassert_equal(ret, -10379, "strtol base = 10 failed");
673 	ret = strtol(buf4, NULL, 16);
674 	zassert_equal(ret, 17004974, "strtol base = 16 failed");
675 	ret = strtol(buf4, NULL, 0);
676 	zassert_equal(ret, 17004974, "strtol base = 16 failed");
677 	ret = strtol(buf5, NULL, 0);
678 	zassert_equal(ret, 17004974, "strtol base = 16 failed");
679 	ret = strtol(buf6, NULL, 0);
680 	zassert_equal(ret, 543, "strtol base = 8 failed");
681 	ret = strtol(buf7, NULL, 0);
682 	zassert_equal(ret, 1037, "strtol base = 10 failed");
683 	ret = strtol(buf8, NULL, 10);
684 	zassert_not_equal(ret, 1037, "strtol base = 10 failed");
685 	ret = strtol(buf9, NULL, 10);
686 	zassert_not_equal(ret, 1037, "strtol base = 10 failed");
687 	ret = strtol(buf10, NULL, 10);
688 	zassert_not_equal(ret, 1037, "strtol base = 10 failed");
689 
690 	ret = strtol(str_normal, &stop, 10);
691 	zassert_equal(ret, -1011, "strtol base = 10 failed");
692 	zassert_true((strcmp(stop, " This stopped it") == 0),
693 		"strtol get stop failed");
694 
695 	ret = strtol(str_abnormal, &stop, 0);
696 	zassert_equal(ret, 0, "strtol base = 0 failed");
697 	zassert_true((strcmp(stop, "ABCDEFGH") == 0),
698 		"strtol get stop failed");
699 
700 #if LONG_MAX > 2147483647
701 	char border1[] = "-9223372036854775809";
702 	char border2[] = "+9223372036854775808";
703 	char border3[] = "+9223372036854775806";
704 	char border4[] = "922337203685477580000000";
705 
706 	ret = strtol(border1, NULL, 10);
707 	zassert_equal(ret, LONG_MIN, "strtol base = 10 failed");
708 	ret = strtol(border2, NULL, 10);
709 	zassert_equal(ret, LONG_MAX, "strtol base = 10 failed");
710 	ret = strtol(border3, NULL, 10);
711 	zassert_equal(ret, 9223372036854775806, "strtol base = 10 failed");
712 	ret = strtol(border4, NULL, 10);
713 	zassert_equal(ret, LONG_MAX, "strtol base = 10 failed");
714 #else
715 	char border1[] = "-2147483649";
716 	char border2[] = "+2147483648";
717 	char border3[] = "+2147483646";
718 	char border4[] = "214748364000000";
719 
720 	ret = strtol(border1, NULL, 10);
721 	zassert_equal(ret, LONG_MIN, "strtol base = 10 failed");
722 	ret = strtol(border2, NULL, 10);
723 	zassert_equal(ret, LONG_MAX, "strtol base = 10 failed");
724 	ret = strtol(border3, NULL, 10);
725 	zassert_equal(ret, 2147483646, "strtol base = 10 failed");
726 	ret = strtol(border4, NULL, 10);
727 	zassert_equal(ret, LONG_MAX, "strtol base = 10 failed");
728 #endif
729 }
730 
731 /**
732  *
733  * @brief test strtoul function
734  *
735  * @see strtoul().
736  *
737  */
test_strtoul(void)738 void test_strtoul(void)
739 {
740 	static const char buf1[] = "+10379aegi";
741 	static const char buf2[] = "   -10379aegi";
742 	static const char buf3[] = "-010379aegi";
743 	static const char buf4[] = "0x10379aegi";
744 	static const char buf5[] = "0X10379aegi";
745 	static const char buf6[] = "01037aegi";
746 	static const char buf7[] = "1037aegi";
747 	static const char buf8[] = "++1037aegi";
748 	static const char buf9[] = "A1037aegi";
749 	static const char buf10[] = "a1037aegi";
750 	static const char str_normal[] = "-1011 This stopped it";
751 	static const char str_abnormal[] = "ABCDEFGH";
752 	char *stop = NULL;
753 	long ret;
754 
755 	/* test function strtol() */
756 	ret = strtoul(buf3, NULL, 8);
757 	zassert_equal(ret, -543, "strtol base = 8 failed");
758 	ret = strtoul(buf1, NULL, 10);
759 	zassert_equal(ret, 10379, "strtol base = 10 failed");
760 	ret = strtoul(buf2, NULL, 10);
761 	zassert_equal(ret, -10379, "strtol base = 10 failed");
762 	ret = strtoul(buf4, NULL, 16);
763 	zassert_equal(ret, 17004974, "strtol base = 16 failed");
764 	ret = strtoul(buf4, NULL, 0);
765 	zassert_equal(ret, 17004974, "strtol base = 16 failed");
766 	ret = strtoul(buf5, NULL, 0);
767 	zassert_equal(ret, 17004974, "strtol base = 16 failed");
768 	ret = strtoul(buf6, NULL, 0);
769 	zassert_equal(ret, 543, "strtol base = 8 failed");
770 	ret = strtoul(buf7, NULL, 0);
771 	zassert_equal(ret, 1037, "strtol base = 10 failed");
772 	ret = strtoul(buf8, NULL, 10);
773 	zassert_not_equal(ret, 1037, "strtol base = 10 failed");
774 	ret = strtoul(buf9, NULL, 10);
775 	zassert_not_equal(ret, 1037, "strtol base = 10 failed");
776 	ret = strtoul(buf10, NULL, 10);
777 	zassert_not_equal(ret, 1037, "strtol base = 10 failed");
778 
779 	ret = strtoul(str_normal, &stop, 10);
780 	zassert_equal(ret, -1011, "strtol base = 10 failed");
781 	zassert_true((strcmp(stop, " This stopped it") == 0),
782 		"strtol get stop failed");
783 
784 	ret = strtoul(str_abnormal, &stop, 0);
785 	zassert_equal(ret, 0, "strtol base = 0 failed");
786 	zassert_true((strcmp(stop, "ABCDEFGH") == 0),
787 		"strtol get stop failed");
788 
789 #if LONG_MAX > 2147483647
790 	char border1[] = "18446744073709551615";
791 	char border2[] = "-18446744073709551615000";
792 	char border3[] = "18446744073709551619";
793 
794 	ret = strtoul(border1, NULL, 10);
795 	zassert_equal(ret, ULONG_MAX, "strtol base = 10 failed");
796 	ret = strtoul(border2, NULL, 10);
797 	zassert_equal(ret, ULONG_MAX, "strtol base = 10 failed");
798 	ret = strtoul(border3, NULL, 10);
799 	zassert_equal(ret, ULONG_MAX, "strtol base = 10 failed");
800 
801 #else
802 	char border1[] = "+4294967295";
803 	char border2[] = "-4294967295000";
804 	char border3[] = "+4294967299";
805 
806 	ret = strtoul(border1, NULL, 10);
807 	zassert_equal(ret, ULONG_MAX, "strtol base = 10 failed");
808 	ret = strtoul(border2, NULL, 10);
809 	zassert_equal(ret, ULONG_MAX, "strtol base = 10 failed");
810 	ret = strtoul(border3, NULL, 10);
811 	zassert_equal(ret, ULONG_MAX, "strtol base = 10 failed");
812 #endif
813 }
814 
815 /**
816  *
817  * @brief test convert function
818  *
819  */
test_tolower_toupper(void)820 void test_tolower_toupper(void)
821 {
822 	static const char test[] = "Az09Za{#!";
823 	static const char toup[] = "AZ09ZA{#!";
824 	static const char tolw[] = "az09za{#!";
825 	char up[11];
826 	char lw[11];
827 	int i = 0;
828 
829 	for (; i < strlen(test); i++) {
830 		up[i] = toupper(test[i]);
831 		lw[i] = tolower(test[i]);
832 	}
833 	lw[i] = up[i] = '\0';
834 
835 	zassert_equal(strcmp(up, toup), 0, "toupper error");
836 	zassert_equal(strcmp(lw, tolw), 0, "tolower error");
837 }
838 
test_strtok_r_do(char * str,char * sep,int tlen,const char * const * toks,bool expect)839 void test_strtok_r_do(char *str, char *sep, int tlen,
840 		      const char * const *toks, bool expect)
841 {
842 	int len = 0;
843 	char *state, *tok, buf[64+1] = {0};
844 
845 	strncpy(buf, str, 64);
846 
847 	tok = strtok_r(buf, sep, &state);
848 	while (tok && len < tlen) {
849 		if (strcmp(tok, toks[len]) != 0) {
850 			break;
851 		}
852 		tok = strtok_r(NULL, sep, &state);
853 		len++;
854 	}
855 	if (expect) {
856 		zassert_equal(len, tlen,
857 			      "strtok_r error '%s' / '%s'", str, sep);
858 	} else {
859 		zassert_not_equal(len, tlen,
860 				  "strtok_r error '%s' / '%s'", str, sep);
861 	}
862 }
863 
test_strtok_r(void)864 void test_strtok_r(void)
865 {
866 	static const char * const tc01[] = { "1", "2", "3", "4", "5" };
867 
868 	test_strtok_r_do("1,2,3,4,5",           ",",  5, tc01, true);
869 	test_strtok_r_do(",, 1 ,2  ,3   4,5  ", ", ", 5, tc01, true);
870 	test_strtok_r_do("1,,,2 3,,,4 5",       ", ", 5, tc01, true);
871 	test_strtok_r_do("1,2 3,,,4 5  ",       ", ", 5, tc01, true);
872 	test_strtok_r_do("0,1,,,2 3,,,4 5",     ", ", 5, tc01, false);
873 	test_strtok_r_do("1,,,2 3,,,4 5",       ",",  5, tc01, false);
874 	test_strtok_r_do("A,,,2,3,,,4 5",       ",",  5, tc01, false);
875 	test_strtok_r_do("1,,,2,3,,,",          ",",  5, tc01, false);
876 	test_strtok_r_do("1|2|3,4|5",           "| ", 5, tc01, false);
877 }
878 
879 /**
880  *
881  * @brief Test time function
882  *
883  * @see gmtime(),gmtime_r().
884  */
test_time(void)885 void test_time(void)
886 {
887 	time_t tests1 = 0;
888 	time_t tests2 = -5;
889 	time_t tests3 = -214748364800;
890 	time_t tests4 = 951868800;
891 
892 	struct tm tp;
893 
894 	zassert_not_null(gmtime(&tests1), "gmtime failed");
895 	zassert_not_null(gmtime(&tests2), "gmtime failed");
896 
897 	tp.tm_wday = -5;
898 	zassert_not_null(gmtime_r(&tests3, &tp), "gmtime_r failed");
899 	zassert_not_null(gmtime_r(&tests4, &tp), "gmtime_r failed");
900 }
901 
902 /**
903  *
904  * @brief Test rand function
905  *
906  */
test_rand(void)907 void test_rand(void)
908 {
909 	int a;
910 
911 	a = rand();
912 	/* The default seed is 1 */
913 	zassert_equal(a, 1103527590, "rand failed");
914 }
915 
916 /**
917  *
918  * @brief Test srand function
919  *
920  */
test_srand(void)921 void test_srand(void)
922 {
923 	int a;
924 
925 	srand(0);
926 	a = rand();
927 	zassert_equal(a, 12345, "srand with seed 0 failed");
928 
929 	srand(1);
930 	a = rand();
931 	zassert_equal(a, 1103527590, "srand with seed 1 failed");
932 
933 	srand(10);
934 	a = rand();
935 	zassert_equal(a, 297746555, "srand with seed 10 failed");
936 
937 	srand(UINT_MAX - 1);
938 	a = rand();
939 	zassert_equal(a, 2087949151, "srand with seed UINT_MAX - 1 failed");
940 
941 	srand(UINT_MAX);
942 	a = rand();
943 	zassert_equal(a, 1043980748, "srand with seed UINT_MAX failed");
944 }
945 
946 /**
947  *
948  * @brief Test rand function for reproducibility
949  *
950  */
test_rand_reproducibility(void)951 void test_rand_reproducibility(void)
952 {
953 	int a;
954 	int b;
955 	int c;
956 
957 	srand(0);
958 	a = rand();
959 	zassert_equal(a, 12345, "srand with seed 0 failed");
960 	srand(0);
961 	b = rand();
962 	zassert_equal(b, 12345, "srand with seed 0 failed (2nd)");
963 	srand(0);
964 	c = rand();
965 	zassert_equal(c, 12345, "srand with seed 0 failed (3rd)");
966 
967 	srand(1);
968 	a = rand();
969 	zassert_equal(a, 1103527590, "srand with seed 1 failed");
970 	srand(1);
971 	b = rand();
972 	zassert_equal(b, 1103527590, "srand with seed 1 failed (2nd)");
973 	srand(1);
974 	c = rand();
975 	zassert_equal(c, 1103527590, "srand with seed 1 failed (3rd)");
976 
977 	srand(10);
978 	a = rand();
979 	zassert_equal(a, 297746555, "srand with seed 10 failed");
980 	srand(10);
981 	b = rand();
982 	zassert_equal(b, 297746555, "srand with seed 10 failed (2nd)");
983 	srand(10);
984 	c = rand();
985 	zassert_equal(c, 297746555, "srand with seed 10 failed (3rd)");
986 
987 	srand(UINT_MAX - 1);
988 	a = rand();
989 	zassert_equal(a, 2087949151, "srand with seed UINT_MAX - 1 failed");
990 	srand(UINT_MAX - 1);
991 	b = rand();
992 	zassert_equal(b, 2087949151, "srand with seed UINT_MAX - 1 failed (2nd)");
993 	srand(UINT_MAX - 1);
994 	c = rand();
995 	zassert_equal(c, 2087949151, "srand with seed UINT_MAX - 1 failed (3rd)");
996 
997 	srand(UINT_MAX);
998 	a = rand();
999 	zassert_equal(a, 1043980748, "srand with seed UINT_MAX failed");
1000 	srand(UINT_MAX);
1001 	b = rand();
1002 	zassert_equal(b, 1043980748, "srand with seed UINT_MAX failed (2nd)");
1003 	srand(UINT_MAX);
1004 	c = rand();
1005 	zassert_equal(c, 1043980748, "srand with seed UINT_MAX failed (3rd)");
1006 }
1007 
1008 /**
1009  *
1010  * @brief test abort functions
1011  *
1012  * @see abort().
1013  */
test_abort(void)1014 void test_abort(void)
1015 {
1016 	int a = 0;
1017 
1018 	ztest_set_fault_valid(true);
1019 	abort();
1020 	zassert_equal(a, 0, "abort failed");
1021 }
1022 
1023 /**
1024  *
1025  * @brief test _exit functions
1026  *
1027  */
exit_program(void * p1,void * p2,void * p3)1028 static void exit_program(void *p1, void *p2, void *p3)
1029 {
1030 	_exit(1);
1031 }
1032 
test_exit(void)1033 void test_exit(void)
1034 {
1035 	int a = 0;
1036 
1037 	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, exit_program,
1038 					NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
1039 	k_sleep(K_MSEC(10));
1040 	k_thread_abort(tid);
1041 	zassert_equal(a, 0, "exit failed");
1042 }
1043 
1044 /**
1045  *
1046  * @brief Test qsort function
1047  *
1048  * @see qsort()
1049  */
1050 extern void test_qsort(void);
1051 
1052 /**
1053  * @}
1054  */
1055 
test_main(void)1056 void test_main(void)
1057 {
1058 	ztest_test_suite(test_c_lib,
1059 			 ztest_unit_test(test_limits),
1060 			 ztest_unit_test(test_ssize_t),
1061 			 ztest_unit_test(test_stdbool),
1062 			 ztest_unit_test(test_stddef),
1063 			 ztest_unit_test(test_stdint),
1064 			 ztest_unit_test(test_memcmp),
1065 			 ztest_unit_test(test_strchr),
1066 			 ztest_unit_test(test_strcpy),
1067 			 ztest_unit_test(test_strncpy),
1068 			 ztest_unit_test(test_memset),
1069 			 ztest_unit_test(test_strlen),
1070 			 ztest_unit_test(test_strcmp),
1071 			 ztest_unit_test(test_strxspn),
1072 			 ztest_unit_test(test_bsearch),
1073 			 ztest_unit_test(test_abs),
1074 			 ztest_unit_test(test_atoi),
1075 			 ztest_unit_test(test_strncmp),
1076 			 ztest_unit_test(test_strtol),
1077 			 ztest_unit_test(test_strtoul),
1078 			 ztest_unit_test(test_checktype),
1079 			 ztest_unit_test(test_memchr),
1080 			 ztest_unit_test(test_memcpy),
1081 			 ztest_unit_test(test_memmove),
1082 			 ztest_unit_test(test_time),
1083 			 ztest_unit_test(test_rand),
1084 			 ztest_unit_test(test_srand),
1085 			 ztest_unit_test(test_rand_reproducibility),
1086 			 ztest_unit_test(test_abort),
1087 			 ztest_unit_test(test_exit),
1088 			 ztest_unit_test(test_str_operate),
1089 			 ztest_unit_test(test_tolower_toupper),
1090 			 ztest_unit_test(test_strtok_r),
1091 			 ztest_unit_test(test_qsort)
1092 			 );
1093 	ztest_run_test_suite(test_c_lib);
1094 }
1095