1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-01-12     Meco Man     The first version.
9  */
10 
11 #include "posix/string.h"
12 #include <ctype.h>
13 #include <rtthread.h>
14 #include <stdlib.h>
15 
16 #ifndef RT_USING_PICOLIBC
17 /**
18  * @brief erases the data in the n bytes of the memory starting at the
19  *        location pointed to by s, by writing zeros (bytes containing '\0') to that area.
20  *
21  * @note  The bzero() function is deprecated (marked as LEGACY in POSIX. 1-2001).
22  */
bzero(void * s,size_t n)23 void bzero(void* s, size_t n)
24 {
25     rt_memset(s, 0, n);
26 }
27 #endif
28 
bcopy(const void * src,void * dest,size_t n)29 void bcopy(const void* src, void* dest, size_t n)
30 {
31     rt_memcpy(dest, src, n);
32 }
33 
bcmp(const void * s1,const void * s2,size_t n)34 int bcmp(const void* s1, const void* s2, size_t n)
35 {
36     return rt_memcmp(s1, s2, n);
37 }
38 
explicit_bzero(void * s,size_t n)39 void explicit_bzero(void* s, size_t n)
40 {
41     volatile char* vs = (volatile char*)s;
42     while (n)
43     {
44         *vs++ = 0;
45         n--;
46     }
47 }
48 
index(const char * s,int c)49 char *index(const char* s, int c)
50 {
51     return strchr(s, c);
52 }
53 
rindex(const char * s,int c)54 char *rindex(const char* s, int c)
55 {
56     return strrchr(s, c);
57 }
58 
ffs(int i)59 int ffs(int i)
60 {
61     int bit;
62 
63     if (0 == i)
64         return 0;
65 
66     for (bit = 1; !(i & 1); ++bit)
67         i >>= 1;
68     return bit;
69 }
70 
ffsl(long i)71 int ffsl(long i)
72 {
73     int bit;
74 
75     if (0 == i)
76         return 0;
77 
78     for (bit = 1; !(i & 1); ++bit)
79         i >>= 1;
80     return bit;
81 }
82 
ffsll(long long i)83 int ffsll(long long i)
84 {
85     int bit;
86 
87     if (0 == i)
88         return 0;
89 
90     for (bit = 1; !(i & 1); ++bit)
91         i >>= 1;
92     return bit;
93 }
94 
95 /**
96  * @brief The memchr() function scans the initial n bytes of the memory area pointed to
97  *        by s for the first instance of c. Both c and the bytes of the memory area
98  *        pointed to by s are interpreted as unsigned char.
99  *
100  * @note  This function is GNU extension, available since glibc 2.1.91.
101  */
memrchr(const void * ptr,int ch,size_t pos)102 void *memrchr(const void* ptr, int ch, size_t pos)
103 {
104     char* end = (char*)ptr + pos - 1;
105     while (end != ptr)
106     {
107         if (*end == ch)
108             return end;
109         end--;
110     }
111     return (*end == ch) ? (end) : (NULL);
112 }
113 
strnlen(const char * s,size_t maxlen)114 size_t strnlen(const char *s, size_t maxlen)
115 {
116     const char *sc;
117     for (sc = s; maxlen != 0 && *sc != '\0'; maxlen--, ++sc);
118     return sc - s;
119 }
120 
strchrnul(const char * s,int c)121 char *strchrnul(const char* s, int c)
122 {
123     while (*s != '\0' && *s != c)
124         s++;
125     return (char*)s;
126 }
127 
strcasecmp(const char * s1,const char * s2)128 int strcasecmp(const char* s1, const char* s2)
129 {
130     const unsigned char* u1 = (const unsigned char*)s1;
131     const unsigned char* u2 = (const unsigned char*)s2;
132     int result;
133 
134     while ((result = tolower(*u1) - tolower(*u2)) == 0 && *u1 != 0)
135     {
136         u1++;
137         u2++;
138     }
139 
140     return result;
141 }
142 
strncasecmp(const char * s1,const char * s2,size_t n)143 int strncasecmp(const char* s1, const char* s2, size_t n)
144 {
145     const unsigned char* u1 = (const unsigned char*)s1;
146     const unsigned char* u2 = (const unsigned char*)s2;
147     int result;
148 
149     for (; n != 0; n--)
150     {
151         result = tolower(*u1) - tolower(*u2);
152         if (result)
153             return result;
154         if (*u1 == 0)
155             return 0;
156         u1++;
157         u2++;
158     }
159     return 0;
160 }
161 
strdup(const char * s)162 char *strdup(const char *s)
163 {
164     char *news = (char *)malloc(strlen(s) + 1);
165 
166     if (news)
167     {
168         strcpy(news, s);
169     }
170 
171     return news;
172 }
173 
strndup(const char * s,size_t size)174 char *strndup(const char *s, size_t size)
175 {
176     size_t nsize = strnlen(s, size);
177     char *news = (char *)malloc(nsize + 1);
178     if (news)
179     {
180         rt_memcpy(news, s, nsize);
181         news[nsize] = '\0';
182     }
183 
184     return news;
185 }
186 
strtok_r(char * str,const char * delim,char ** saveptr)187 rt_weak char *strtok_r(char *str, const char *delim, char **saveptr)
188 {
189     char *pbegin;
190     char *pend = NULL;
191 
192     if (str)
193     {
194         pbegin = str;
195     }
196     else if (saveptr && *saveptr)
197     {
198         pbegin = *saveptr;
199     }
200     else
201     {
202         return NULL;
203     }
204 
205     for (;*pbegin && strchr(delim, *pbegin) != NULL; pbegin++);
206 
207     if (!*pbegin)
208     {
209         return NULL;
210     }
211 
212     for (pend = pbegin + 1; *pend && strchr(delim, *pend) == NULL; pend++);
213 
214     if (*pend)
215     {
216         *pend++ = '\0';
217     }
218 
219     if (saveptr)
220     {
221         *saveptr = pend;
222     }
223 
224     return pbegin;
225 }
226