2 * AcessOS Basic C Library
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 while(*s1 && *s1 == *s2) {
21 return (int)*s1 - (int)*s2;
25 * \fn EXPORT int strncmp(const char *s1, const char *s2)
26 * \brief Compare two strings
28 EXPORT int strncmp(const char *s1, const char *s2, size_t n)
30 while(n && *s1 && *s1 == *s2)
38 return (int)*s1 - (int)*s2;
41 EXPORT int strcasecmp(const char *s1, const char *s2)
44 while( (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0' ) {
50 EXPORT int strncasecmp(const char *s1, const char *s2, size_t n)
53 if( n == 0 ) return 0;
54 while(n -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') {
61 * \fn EXPORT char *strcpy(char *dst, const char *src)
62 * \brief Copy a string to another
64 EXPORT char *strcpy(char *dst, const char *src)
76 * \fn EXPORT char *strncpy(char *dst, const char *src)
77 * \brief Copy at most \a num characters from \a src to \a dst
80 EXPORT char *strncpy(char *dst, const char *src, size_t num)
83 while(*src && num--) *to++ = *src++;
89 * \fn EXPORT char *strcat(char *dst, const char *src)
90 * \brief Append a string onto another
92 EXPORT char *strcat(char *dst, const char *src)
98 while(*src) *to++ = *src++;
104 EXPORT char *strncat(char *dst, const char *src, size_t n)
110 while(*src && n--) *to++ = *src++;
117 * \brief Get the length of a string
119 EXPORT size_t strlen(const char *str)
122 for(retval = 0; *str != '\0'; str++, retval++);
127 * \brief Get the length of a string, with a maximum of \a maxlen
129 * Gets the length of a string (excluding the terminating \0 byte)
131 EXPORT size_t strnlen(const char *str, size_t maxlen)
134 for( len = 0; maxlen -- && *str; str ++, len ++ );
139 * \fn EXPORT char *strdup(const char *str)
140 * \brief Duplicate a string using heap memory
141 * \note Defined in POSIX Spec, not C spec
143 EXPORT char *strdup(const char *str)
145 size_t len = strlen(str);
146 char *ret = malloc(len+1);
147 if(ret == NULL) return NULL;
153 * \fn EXPORT char *strndup(const char *str, size_t maxlen)
154 * \brief Duplicate a string into the heap with a maximum length
155 * \param str Input string buffer
156 * \param maxlen Maximum valid size of the \a str buffer
157 * \return Heap string with the same value of \a str
159 EXPORT char *strndup(const char *str, size_t maxlen)
163 for( len = 0; len < maxlen && str[len]; len ++) ;
164 ret = malloc( len + 1);
165 memcpy( ret, str, len );
171 * \fn EXPORT char *strchr(char *str, int character)
172 * \brief Locate a character in a string
174 EXPORT char *strchr(const char *str, int character)
178 if(*str == character)
185 * \fn EXPORT char *strrchr(char *str, int character)
186 * \brief Locate the last occurance of a character in a string
188 EXPORT char *strrchr(const char *str, int character)
194 if(str[i] == character)
195 return (void*)&str[i];
201 * \fn EXPORT char *strstr(char *str1, const char *str2)
202 * \brief Search a \a str1 for the first occurance of \a str2
204 EXPORT char *strstr(const char *str1, const char *str2)
206 const char *test = str2;
210 if(*test == '\0') return (char*)str1;
211 if(*str1 == *test) test++;
219 * \fn EXPORT void *memset(void *dest, int val, size_t num)
220 * \brief Clear memory with the specified value
222 EXPORT void *memset(void *dest, int val, size_t num)
224 unsigned char *p = dest;
225 while(num--) *p++ = val;
230 * \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
231 * \brief Copy one memory area to another
233 EXPORT void *memcpy(void *__dest, const void *__src, size_t count)
235 const int wordmask = sizeof(void*)-1;
236 uintptr_t src = (uintptr_t)__src;
237 uintptr_t dst = (uintptr_t)__dest;
239 if( count < sizeof(void*)*2 || (dst & wordmask) != (src & wordmask) )
242 const char *sp = __src;
243 while(count--) *dp++ = *sp ++;
245 // TODO: Bulk aligned copies
247 else if(count > 128 && (dst & 15) == (src & 15) )
250 for( ; dst & 15; count -- )
251 *(char*)dst++ = *(char*)src++;
252 memcpy_16byte(dst, src, count / 16);
257 *(char*)dst++ = *(char*)src++;
263 for( ; count && (dst & wordmask) != 0; count -- )
264 *(char*)dst++ = *(char*)src++;
266 dp = (void*)dst; sp = (void*)src;
267 while( count >= sizeof(void*) )
270 count -= sizeof(void*);
272 dst = (uintptr_t)dp; src = (uintptr_t)sp;
273 for( ; count; count -- )
274 *(char*)dst++ = *(char*)src++;
281 * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
282 * \brief Copy data in memory, avoiding overlap problems
284 EXPORT void *memmove(void *dest, const void *src, size_t count)
286 const char *sp = (const char *)src;
287 char *dp = (char *)dest;
288 // Check if the areas overlap
290 memcpy(dest, src, count);
291 else if( dp >= sp+count )
292 memcpy(dest, src, count);
296 dp[count] = sp[count];
307 * \fn EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
308 * \brief Compare two regions of memory
309 * \param mem1 Region 1
310 * \param mem2 Region 2
311 * \param count Number of bytes to check
313 EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
315 const unsigned char *p1 = mem1, *p2 = mem2;
327 * \fn EXPORT void *memchr(void *ptr, int value, size_t num)
328 * \brief Locates the first occurence of \a value starting at \a ptr
329 * \param ptr Starting memory location
330 * \param value Value to find
331 * \param num Size of memory area to check
333 EXPORT void *memchr(const void *ptr, int value, size_t num)
337 if( *(const unsigned char*)ptr == (unsigned char)value )
344 EXPORT size_t strcspn(const char *haystack, const char *reject)
350 for( i = 0; reject[i] && reject[i] == *haystack; i ++ );
352 if( reject[i] ) return ret;
358 EXPORT size_t strspn(const char *haystack, const char *accept)
364 for( i = 0; accept[i] && accept[i] == *haystack; i ++ );
366 if( !accept[i] ) return ret;
372 char *strtok(char *str, const char *delim)
374 static char *__saveptr;
375 return strtok_r(str, delim, &__saveptr);
377 char *strtok_r(char *str, const char *delim, char **saveptr)
379 char *pos = (str ? str : *saveptr);
381 while( strchr(delim, *pos) )
388 while( !strchr(delim, *pos) )
391 // Cap the returned string
392 // - If we're at the end of the original string, don't shift pos