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)
90 while(*src && num--) *to++ = *src++;
96 * \fn EXPORT char *strcat(char *dst, const char *src)
97 * \brief Append a string onto another
99 EXPORT char *strcat(char *dst, const char *src)
105 while(*src) *to++ = *src++;
111 EXPORT char *strncat(char *dst, const char *src, size_t n)
117 while(*src && n--) *to++ = *src++;
124 * \brief Get the length of a string
126 EXPORT size_t strlen(const char *str)
129 for(retval = 0; *str != '\0'; str++, retval++);
134 * \brief Get the length of a string, with a maximum of \a maxlen
136 * Gets the length of a string (excluding the terminating \0 byte)
138 EXPORT size_t strnlen(const char *str, size_t maxlen)
141 for( len = 0; maxlen -- && *str; str ++, len ++ )
147 * \fn EXPORT char *strdup(const char *str)
148 * \brief Duplicate a string using heap memory
149 * \note Defined in POSIX Spec, not C spec
151 EXPORT char *strdup(const char *str)
153 size_t len = strlen(str);
154 char *ret = malloc(len+1);
155 if(ret == NULL) return NULL;
161 * \fn EXPORT char *strndup(const char *str, size_t maxlen)
162 * \brief Duplicate a string into the heap with a maximum length
163 * \param str Input string buffer
164 * \param maxlen Maximum valid size of the \a str buffer
165 * \return Heap string with the same value of \a str
167 EXPORT char *strndup(const char *str, size_t maxlen)
171 for( len = 0; len < maxlen && str[len]; len ++) ;
172 ret = malloc( len + 1);
173 memcpy( ret, str, len );
179 * \fn EXPORT char *strchr(char *str, int character)
180 * \brief Locate a character in a string
182 EXPORT char *strchr(const char *_str, int character)
184 const unsigned char* str = (const unsigned char*)_str;
187 if( *str == character )
194 * \fn EXPORT char *strrchr(char *str, int character)
195 * \brief Locate the last occurance of a character in a string
197 EXPORT char *strrchr(const char *_str, int character)
199 const unsigned char* str = (const unsigned char*)_str;
200 for( int i = strlen(_str); i--; )
202 if(str[i] == character)
203 return (void*)&str[i];
209 * \fn EXPORT char *strstr(char *str1, const char *str2)
210 * \brief Search a \a str1 for the first occurance of \a str2
212 EXPORT char *strstr(const char *str1, const char *str2)
214 const char *test = str2;
218 if(*test == '\0') return (char*)str1;
219 if(*str1 == *test) test++;
227 * \fn EXPORT void *memset(void *dest, int val, size_t num)
228 * \brief Clear memory with the specified value
230 EXPORT void *memset(void *dest, int val, size_t num)
232 unsigned char *p = dest;
233 while(num--) *p++ = val;
238 * \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
239 * \brief Copy one memory area to another
241 EXPORT void *memcpy(void *__dest, const void *__src, size_t count)
243 const int wordmask = sizeof(void*)-1;
244 uintptr_t src = (uintptr_t)__src;
245 uintptr_t dst = (uintptr_t)__dest;
247 if( count < sizeof(void*)*2 || (dst & wordmask) != (src & wordmask) )
250 const char *sp = __src;
251 while(count--) *dp++ = *sp ++;
253 // TODO: Bulk aligned copies
255 else if(count > 128 && (dst & 15) == (src & 15) )
258 for( ; dst & 15; count -- )
259 *(char*)dst++ = *(char*)src++;
260 memcpy_16byte(dst, src, count / 16);
265 *(char*)dst++ = *(char*)src++;
271 for( ; count && (dst & wordmask) != 0; count -- )
272 *(char*)dst++ = *(char*)src++;
274 dp = (void*)dst; sp = (void*)src;
275 while( count >= sizeof(void*) )
278 count -= sizeof(void*);
280 dst = (uintptr_t)dp; src = (uintptr_t)sp;
281 for( ; count; count -- )
282 *(char*)dst++ = *(char*)src++;
288 // TODO: memccpy (POSIX defined)
291 * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
292 * \brief Copy data in memory, avoiding overlap problems
294 EXPORT void *memmove(void *dest, const void *src, size_t count)
296 const char *sp = (const char *)src;
297 char *dp = (char *)dest;
298 // Check if the areas overlap
300 memcpy(dest, src, count);
301 else if( dp >= sp+count )
302 memcpy(dest, src, count);
306 dp[count] = sp[count];
317 * \fn EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
318 * \brief Compare two regions of memory
319 * \param mem1 Region 1
320 * \param mem2 Region 2
321 * \param count Number of bytes to check
323 EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
325 const unsigned char *p1 = mem1, *p2 = mem2;
329 return (int)*p1 - (int)*p2;
337 * \fn EXPORT void *memchr(void *ptr, int value, size_t num)
338 * \brief Locates the first occurence of \a value starting at \a ptr
339 * \param ptr Starting memory location
340 * \param value Value to find
341 * \param num Size of memory area to check
343 EXPORT void *memchr(const void *ptr, int value, size_t num)
345 const unsigned char* buf = ptr;
348 if( *buf == (unsigned char)value )
355 EXPORT size_t strcspn(const char *haystack, const char *reject)
360 for( int i = 0; reject[i]; i ++ )
362 if( reject[i] == *haystack )
370 EXPORT size_t strspn(const char *haystack, const char *accept)
375 for( int i = 0; accept[i]; i ++ )
377 if( accept[i] != *haystack )
385 EXPORT char *strpbrk(const char *haystack, const char *accept)
389 for( int i = 0; accept[i]; i ++ )
391 if( accept[i] == *haystack )
392 return (char*)haystack;
399 char *strtok(char *str, const char *delim)
401 static char *__saveptr;
402 return strtok_r(str, delim, &__saveptr);
404 char *strtok_r(char *str, const char *delim, char **saveptr)
406 char *pos = (str ? str : *saveptr);
408 while( strchr(delim, *pos) )
415 while( !strchr(delim, *pos) )
418 // Cap the returned string
419 // - If we're at the end of the original string, don't shift pos