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
187 * \note The terminating NUL is part of the string
189 EXPORT char *strchr(const char *_str, int character)
191 const unsigned char* str = (const unsigned char*)_str;
194 if( *str == character )
201 * \fn EXPORT char *strrchr(char *str, int character)
202 * \brief Locate the last occurance of a character in a string
204 EXPORT char *strrchr(const char *_str, int character)
206 const unsigned char* str = (const unsigned char*)_str;
207 size_t i = strlen(_str);
210 if(str[i] == character)
211 return (void*)&str[i];
217 * \fn EXPORT char *strstr(char *str1, const char *str2)
218 * \brief Search a \a str1 for the first occurance of \a str2
220 EXPORT char *strstr(const char *str1, const char *str2)
222 const char *test = str2;
226 if(*test == '\0') return (char*)str1;
227 if(*str1 == *test) test++;
235 * \fn EXPORT void *memset(void *dest, int val, size_t num)
236 * \brief Clear memory with the specified value
238 EXPORT void *memset(void *dest, int val, size_t num)
240 unsigned char *p = dest;
241 while(num--) *p++ = val;
246 * \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
247 * \brief Copy one memory area to another
249 EXPORT void *memcpy(void *__dest, const void *__src, size_t count)
251 const int wordmask = sizeof(void*)-1;
252 uintptr_t src = (uintptr_t)__src;
253 uintptr_t dst = (uintptr_t)__dest;
255 if( count < sizeof(void*)*2 || (dst & wordmask) != (src & wordmask) )
258 const char *sp = __src;
259 while(count--) *dp++ = *sp ++;
261 // TODO: Bulk aligned copies
263 else if(count > 128 && (dst & 15) == (src & 15) )
266 for( ; dst & 15; count -- )
267 *(char*)dst++ = *(char*)src++;
268 memcpy_16byte(dst, src, count / 16);
273 *(char*)dst++ = *(char*)src++;
279 for( ; count && (dst & wordmask) != 0; count -- )
280 *(char*)dst++ = *(char*)src++;
282 dp = (void*)dst; sp = (void*)src;
283 while( count >= sizeof(void*) )
286 count -= sizeof(void*);
288 dst = (uintptr_t)dp; src = (uintptr_t)sp;
289 for( ; count; count -- )
290 *(char*)dst++ = *(char*)src++;
296 // TODO: memccpy (POSIX defined)
299 * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
300 * \brief Copy data in memory, avoiding overlap problems
302 EXPORT void *memmove(void *dest, const void *src, size_t count)
304 const char *sp = (const char *)src;
305 char *dp = (char *)dest;
306 // Check if the areas overlap
308 memcpy(dest, src, count);
309 else if( dp >= sp+count )
310 memcpy(dest, src, count);
314 dp[count] = sp[count];
325 * \fn EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
326 * \brief Compare two regions of memory
327 * \param mem1 Region 1
328 * \param mem2 Region 2
329 * \param count Number of bytes to check
331 EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
333 const unsigned char *p1 = mem1, *p2 = mem2;
337 return (int)*p1 - (int)*p2;
345 * \fn EXPORT void *memchr(void *ptr, int value, size_t num)
346 * \brief Locates the first occurence of \a value starting at \a ptr
347 * \param ptr Starting memory location
348 * \param value Value to find
349 * \param num Size of memory area to check
351 EXPORT void *memchr(const void *ptr, int value, size_t num)
353 const unsigned char* buf = ptr;
356 if( *buf == (unsigned char)value )
363 EXPORT size_t strcspn(const char *haystack, const char *reject)
368 for( int i = 0; reject[i]; i ++ )
370 if( reject[i] == *haystack )
378 EXPORT size_t strspn(const char *haystack, const char *accept)
383 for( int i = 0; accept[i]; i ++ )
385 if( accept[i] != *haystack )
393 EXPORT char *strpbrk(const char *haystack, const char *accept)
397 for( int i = 0; accept[i]; i ++ )
399 if( accept[i] == *haystack )
400 return (char*)haystack;
407 char *strtok(char *str, const char *delim)
409 static char *__saveptr;
410 return strtok_r(str, delim, &__saveptr);
412 char *strtok_r(char *str, const char *delim, char **saveptr)
414 char *pos = (str ? str : *saveptr);
416 while( strchr(delim, *pos) )
423 while( !strchr(delim, *pos) )
426 // Cap the returned string
427 // - If we're at the end of the original string, don't shift pos