226 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
|  * Copyright (c) 2006-2022, RT-Thread Development Team
 | |
|  *
 | |
|  * SPDX-License-Identifier: Apache-2.0
 | |
|  *
 | |
|  * Change Logs:
 | |
|  * Date           Author       Notes
 | |
|  * 2022-01-12     Meco Man     The first version.
 | |
|  */
 | |
| 
 | |
| #include "posix/string.h"
 | |
| #include <ctype.h>
 | |
| #include <rtthread.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| /**
 | |
|  * @brief erases the data in the n bytes of the memory starting at the
 | |
|  *        location pointed to by s, by writing zeros (bytes containing '\0') to that area.
 | |
|  *
 | |
|  * @note  The bzero() function is deprecated (marked as LEGACY in POSIX. 1-2001).
 | |
|  */
 | |
| #ifndef RT_USING_PICOLIBC
 | |
| void bzero(void* s, size_t n)
 | |
| {
 | |
|     rt_memset(s, 0, n);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void bcopy(const void* src, void* dest, size_t n)
 | |
| {
 | |
|     rt_memcpy(dest, src, n);
 | |
| }
 | |
| 
 | |
| int bcmp(const void* s1, const void* s2, size_t n)
 | |
| {
 | |
|     return rt_memcmp(s1, s2, n);
 | |
| }
 | |
| 
 | |
| void explicit_bzero(void* s, size_t n)
 | |
| {
 | |
|     volatile char* vs = (volatile char*)s;
 | |
|     while (n)
 | |
|     {
 | |
|         *vs++ = 0;
 | |
|         n--;
 | |
|     }
 | |
| }
 | |
| 
 | |
| char* index(const char* s, int c)
 | |
| {
 | |
|     return strchr(s, c);
 | |
| }
 | |
| 
 | |
| char* rindex(const char* s, int c)
 | |
| {
 | |
|     return strrchr(s, c);
 | |
| }
 | |
| 
 | |
| int ffs(int i)
 | |
| {
 | |
|     int bit;
 | |
| 
 | |
|     if (0 == i)
 | |
|         return 0;
 | |
| 
 | |
|     for (bit = 1; !(i & 1); ++bit)
 | |
|         i >>= 1;
 | |
|     return bit;
 | |
| }
 | |
| 
 | |
| int ffsl(long i)
 | |
| {
 | |
|     int bit;
 | |
| 
 | |
|     if (0 == i)
 | |
|         return 0;
 | |
| 
 | |
|     for (bit = 1; !(i & 1); ++bit)
 | |
|         i >>= 1;
 | |
|     return bit;
 | |
| }
 | |
| 
 | |
| int ffsll(long long i)
 | |
| {
 | |
|     int bit;
 | |
| 
 | |
|     if (0 == i)
 | |
|         return 0;
 | |
| 
 | |
|     for (bit = 1; !(i & 1); ++bit)
 | |
|         i >>= 1;
 | |
|     return bit;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief The memchr() function scans the initial n bytes of the memory area pointed to
 | |
|  *        by s for the first instance of c. Both c and the bytes of the memory area
 | |
|  *        pointed to by s are interpreted as unsigned char.
 | |
|  *
 | |
|  * @note  This function is GNU extension, available since glibc 2.1.91.
 | |
|  */
 | |
| void* memrchr(const void* ptr, int ch, size_t pos)
 | |
| {
 | |
|     char* end = (char*)ptr + pos - 1;
 | |
|     while (end != ptr)
 | |
|     {
 | |
|         if (*end == ch)
 | |
|             return end;
 | |
|         end--;
 | |
|     }
 | |
|     return (*end == ch) ? (end) : (NULL);
 | |
| }
 | |
| 
 | |
| size_t strnlen(const char *s, size_t maxlen)
 | |
| {
 | |
|     const char *sc;
 | |
|     for (sc = s; maxlen != 0 && *sc != '\0'; maxlen--, ++sc);
 | |
|     return sc - s;
 | |
| }
 | |
| 
 | |
| char* strchrnul(const char* s, int c)
 | |
| {
 | |
|     while (*s != '\0' && *s != c)
 | |
|         s++;
 | |
|     return (char*)s;
 | |
| }
 | |
| 
 | |
| int strcasecmp(const char* s1, const char* s2)
 | |
| {
 | |
|     const unsigned char* u1 = (const unsigned char*)s1;
 | |
|     const unsigned char* u2 = (const unsigned char*)s2;
 | |
|     int result;
 | |
| 
 | |
|     while ((result = tolower(*u1) - tolower(*u2)) == 0 && *u1 != 0)
 | |
|     {
 | |
|         u1++;
 | |
|         u2++;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| int strncasecmp(const char* s1, const char* s2, size_t n)
 | |
| {
 | |
|     const unsigned char* u1 = (const unsigned char*)s1;
 | |
|     const unsigned char* u2 = (const unsigned char*)s2;
 | |
|     int result;
 | |
| 
 | |
|     for (; n != 0; n--)
 | |
|     {
 | |
|         result = tolower(*u1) - tolower(*u2);
 | |
|         if (result)
 | |
|             return result;
 | |
|         if (*u1 == 0)
 | |
|             return 0;
 | |
|         u1++;
 | |
|         u2++;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| char *strdup(const char *s)
 | |
| {
 | |
|     char *news = (char *)malloc(strlen(s) + 1);
 | |
| 
 | |
|     if (news)
 | |
|     {
 | |
|         strcpy(news, s);
 | |
|     }
 | |
| 
 | |
|     return news;
 | |
| }
 | |
| 
 | |
| char *strndup(const char *s, size_t size)
 | |
| {
 | |
|     size_t nsize = strnlen(s, size);
 | |
|     char *news = (char *)malloc(nsize + 1);
 | |
|     if (news)
 | |
|     {
 | |
|         rt_memcpy(news, s, nsize);
 | |
|         news[nsize] = '\0';
 | |
|     }
 | |
| 
 | |
|     return news;
 | |
| }
 | |
| 
 | |
| rt_weak char *strtok_r(char *str, const char *delim, char **saveptr)
 | |
| {
 | |
|     char *pbegin;
 | |
|     char *pend = NULL;
 | |
| 
 | |
|     if (str)
 | |
|     {
 | |
|         pbegin = str;
 | |
|     }
 | |
|     else if (saveptr && *saveptr)
 | |
|     {
 | |
|         pbegin = *saveptr;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     for (;*pbegin && strchr(delim, *pbegin) != NULL; pbegin++);
 | |
| 
 | |
|     if (!*pbegin)
 | |
|     {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     for (pend = pbegin + 1; *pend && strchr(delim, *pend) == NULL; pend++);
 | |
| 
 | |
|     if (*pend)
 | |
|     {
 | |
|         *pend++ = '\0';
 | |
|     }
 | |
| 
 | |
|     if (saveptr)
 | |
|     {
 | |
|         *saveptr = pend;
 | |
|     }
 | |
| 
 | |
|     return pbegin;
 | |
| }
 |