2 * AcessOS Basic C Library
5 //#include <acess/sys.h>
13 * \fn EXPORT int strcmp(const char *s1, const char *s2)
14 * \brief Compare two strings
16 EXPORT int strcmp(const char *_s1, const char *_s2)
18 return strncmp(_s1, _s2, SIZE_MAX);
22 * \fn EXPORT int strncmp(const char *s1, const char *s2, size_t n)
23 * \brief Compare two strings, stopping after n characters
25 EXPORT int strncmp(const char *_s1, const char *_s2, size_t n)
27 const unsigned char* s1 = (const unsigned char*)_s1;
28 const unsigned char* s2 = (const unsigned char*)_s2;
29 while(n && *s1 && *s1 == *s2)
37 return (int)*s1 - (int)*s2;
40 EXPORT int strcasecmp(const char *_s1, const char *_s2)
42 return strncasecmp(_s1, _s2, SIZE_MAX);
45 EXPORT int strncasecmp(const char *_s1, const char *_s2, size_t n)
47 const unsigned char* s1 = (const unsigned char*)_s1;
48 const unsigned char* s2 = (const unsigned char*)_s2;
49 while( n-- && *s1 && *s2 )
54 rv = toupper(*s1) - toupper(*s2);
57 rv = tolower(*s1) - tolower(*s2);
68 * \fn EXPORT char *strcpy(char *dst, const char *src)
69 * \brief Copy a string to another
71 EXPORT char *strcpy(char *dst, const char *src)
83 * \fn EXPORT char *strncpy(char *dst, const char *src)
84 * \brief Copy at most \a num characters from \a src to \a dst
87 EXPORT char *strncpy(char *dst, const char *src, size_t num)
101 * \fn EXPORT char *strcat(char *dst, const char *src)
102 * \brief Append a string onto another
104 EXPORT char *strcat(char *dst, const char *src)
110 while(*src) *to++ = *src++;
116 EXPORT char *strncat(char *dst, const char *src, size_t n)
122 while(*src && n--) *to++ = *src++;
129 * \brief Get the length of a string
131 EXPORT size_t strlen(const char *str)
134 while(str[len] != '\0')
140 * \brief Get the length of a string, with a maximum of \a maxlen
142 * Gets the length of a string (excluding the terminating \0 byte)
144 EXPORT size_t strnlen(const char *str, size_t maxlen)
147 while( len < maxlen && str[len] != '\0' )
153 * \fn EXPORT char *strdup(const char *str)
154 * \brief Duplicate a string using heap memory
155 * \note Defined in POSIX Spec, not C spec
157 EXPORT char *strdup(const char *str)
159 size_t len = strlen(str);
160 char *ret = malloc(len+1);
161 if(ret == NULL) return NULL;
167 * \fn EXPORT char *strndup(const char *str, size_t maxlen)
168 * \brief Duplicate a string into the heap with a maximum length
169 * \param str Input string buffer
170 * \param maxlen Maximum valid size of the \a str buffer
171 * \return Heap string with the same value of \a str
173 EXPORT char *strndup(const char *str, size_t maxlen)
177 for( len = 0; len < maxlen && str[len]; len ++) ;
178 ret = malloc( len + 1);
179 memcpy( ret, str, len );
185 * \fn EXPORT char *strchr(char *str, int character)
186 * \brief Locate a character in a string
188 EXPORT char *strchr(const char *_str, int character)
190 const unsigned char* str = (const unsigned char*)_str;
193 if( *str == character )
200 * \fn EXPORT char *strrchr(char *str, int character)
201 * \brief Locate the last occurance of a character in a string
203 EXPORT char *strrchr(const char *_str, int character)
205 const unsigned char* str = (const unsigned char*)_str;
206 for( size_t i = strlen(_str); i--; )
208 if(str[i] == character)
209 return (void*)&str[i];
215 * \fn EXPORT char *strstr(char *str1, const char *str2)
216 * \brief Search a \a str1 for the first occurance of \a str2
218 EXPORT char *strstr(const char *str1, const char *str2)
220 const char *test = str2;
224 if(*test == '\0') return (char*)str1;
225 if(*str1 == *test) test++;
233 * \fn EXPORT void *memset(void *dest, int val, size_t num)
234 * \brief Clear memory with the specified value
236 EXPORT void *memset(void *dest, int val, size_t num)
238 unsigned char *p = dest;
239 while(num--) *p++ = val;
244 * \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
245 * \brief Copy one memory area to another
247 EXPORT void *memcpy(void *__dest, const void *__src, size_t count)
249 const int wordmask = sizeof(void*)-1;
250 uintptr_t src = (uintptr_t)__src;
251 uintptr_t dst = (uintptr_t)__dest;
253 if( count < sizeof(void*)*2 || (dst & wordmask) != (src & wordmask) )
256 const char *sp = __src;
257 while(count--) *dp++ = *sp ++;
259 // TODO: Bulk aligned copies
261 else if(count > 128 && (dst & 15) == (src & 15) )
264 for( ; dst & 15; count -- )
265 *(char*)dst++ = *(char*)src++;
266 memcpy_16byte(dst, src, count / 16);
271 *(char*)dst++ = *(char*)src++;
277 for( ; count && (dst & wordmask) != 0; count -- )
278 *(char*)dst++ = *(char*)src++;
280 dp = (void*)dst; sp = (void*)src;
281 while( count >= sizeof(void*) )
284 count -= sizeof(void*);
286 dst = (uintptr_t)dp; src = (uintptr_t)sp;
287 for( ; count; count -- )
288 *(char*)dst++ = *(char*)src++;
294 // TODO: memccpy (POSIX defined)
297 * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
298 * \brief Copy data in memory, avoiding overlap problems
300 EXPORT void *memmove(void *dest, const void *src, size_t count)
302 const char *sp = (const char *)src;
303 char *dp = (char *)dest;
304 // Check if the areas overlap
306 memcpy(dest, src, count);
307 else if( dp >= sp+count )
308 memcpy(dest, src, count);
312 dp[count] = sp[count];
323 * \fn EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
324 * \brief Compare two regions of memory
325 * \param mem1 Region 1
326 * \param mem2 Region 2
327 * \param count Number of bytes to check
329 EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
331 const unsigned char *p1 = mem1, *p2 = mem2;
335 return (int)*p1 - (int)*p2;
343 * \fn EXPORT void *memchr(void *ptr, int value, size_t num)
344 * \brief Locates the first occurence of \a value starting at \a ptr
345 * \param ptr Starting memory location
346 * \param value Value to find
347 * \param num Size of memory area to check
349 EXPORT void *memchr(const void *ptr, int value, size_t num)
351 const unsigned char* buf = ptr;
354 if( *buf == (unsigned char)value )
361 EXPORT size_t strcspn(const char *haystack, const char *reject)
366 for( int i = 0; reject[i]; i ++ )
368 if( reject[i] == *haystack )
376 EXPORT size_t strspn(const char *haystack, const char *accept)
381 for( int i = 0; accept[i]; i ++ )
383 if( accept[i] != *haystack )
391 EXPORT char *strpbrk(const char *haystack, const char *accept)
395 for( int i = 0; accept[i]; i ++ )
397 if( accept[i] == *haystack )
398 return (char*)haystack;
405 char *strtok(char *str, const char *delim)
407 static char *__saveptr;
408 return strtok_r(str, delim, &__saveptr);
410 char *strtok_r(char *str, const char *delim, char **saveptr)
412 char *pos = (str ? str : *saveptr);
414 while( strchr(delim, *pos) )
421 while( !strchr(delim, *pos) )
424 // Cap the returned string
425 // - If we're at the end of the original string, don't shift pos