#include <acess/sys.h>
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include "lib.h"
/**
*/
EXPORT int strcmp(const char *s1, const char *s2)
{
- while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
+ while(*s1 && *s1 == *s2) {
s1++; s2++;
}
return (int)*s1 - (int)*s2;
*/
EXPORT int strncmp(const char *s1, const char *s2, size_t n)
{
+ while(n && *s1 && *s1 == *s2)
+ {
+ s1++; s2++;
+ n --;
+ }
+ if( n == 0 )
+ return 0;
+ else
+ return (int)*s1 - (int)*s2;
+}
+
+EXPORT int strcasecmp(const char *s1, const char *s2)
+{
+ int rv;
+ while( (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0' ) {
+ s1++; s2++;
+ }
+ return rv;
+}
+
+EXPORT int strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ int rv = 0;
if( n == 0 ) return 0;
- while(n -- && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
+ while(n -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') {
s1++; s2++;
}
- return (int)*s1 - (int)*s2;
+ return rv;
}
/**
}
/**
- * \fn EXPORT int strlen(const char *str)
* \brief Get the length of a string
*/
-EXPORT int strlen(const char *str)
+EXPORT size_t strlen(const char *str)
{
- int retval;
- for(retval = 0; *str != '\0'; str++)
- retval++;
+ size_t retval;
+ for(retval = 0; *str != '\0'; str++, retval++);
return retval;
}
+/**
+ * \brief Get the length of a string, with a maximum of \a maxlen
+ *
+ * Gets the length of a string (excluding the terminating \0 byte)
+ */
+EXPORT size_t strnlen(const char *str, size_t maxlen)
+{
+ size_t len;
+ for( len = 0; maxlen -- && *str; str ++, len ++ );
+ return len;
+}
+
/**
* \fn EXPORT char *strdup(const char *str)
* \brief Duplicate a string using heap memory
* \fn EXPORT char *strchr(char *str, int character)
* \brief Locate a character in a string
*/
-EXPORT char *strchr(char *str, int character)
+EXPORT char *strchr(const char *str, int character)
{
- while(*str)
+ for(;*str;str++)
{
- if(*str == character) return str;
+ if(*str == character)
+ return (char*)str;
}
return NULL;
}
* \fn EXPORT char *strrchr(char *str, int character)
* \brief Locate the last occurance of a character in a string
*/
-EXPORT char *strrchr(char *str, int character)
+EXPORT char *strrchr(const char *str, int character)
{
int i;
i = strlen(str)-1;
while(i--)
{
- if(str[i] == character) return &str[i];
+ if(str[i] == character)
+ return (void*)&str[i];
}
return NULL;
}
{
const char *test = str2;
- while(*str1)
+ for(;*str1;str1++)
{
if(*test == '\0') return str1;
if(*str1 == *test) test++;
else test = str2;
- str1 ++;
}
return NULL;
}
* \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
* \brief Copy one memory area to another
*/
-EXPORT void *memcpy(void *dest, const void *src, size_t count)
+EXPORT void *memcpy(void *__dest, const void *__src, size_t count)
{
- char *sp = (char *)src;
- char *dp = (char *)dest;
- for(;count--;) *dp++ = *sp++;
- return dest;
+ const int wordmask = sizeof(void*)-1;
+ uintptr_t src = (uintptr_t)__src;
+ uintptr_t dst = (uintptr_t)__dest;
+
+ if( count < sizeof(void*)*2 || (dst & wordmask) != (src & wordmask) )
+ {
+ char *dp = __dest;
+ const char *sp = __src;
+ while(count--) *dp++ = *sp ++;
+ }
+ // TODO: Bulk aligned copies
+ #if 0
+ else if(count > 128 && (dst & 15) == (src & 15) )
+ {
+ // SSE/bulk copy
+ for( ; dst & 15; count -- )
+ *(char*)dst++ = *(char*)src++;
+ memcpy_16byte(dst, src, count / 16);
+ dst += count & ~15;
+ src += count & ~15;
+ count &= 15;
+ while(count --)
+ *(char*)dst++ = *(char*)src++;
+ }
+ #endif
+ else
+ {
+ void **dp, **sp;
+ for( ; count && (dst & wordmask) != 0; count -- )
+ *(char*)dst++ = *(char*)src++;
+
+ dp = (void*)dst; sp = (void*)src;
+ while( count >= sizeof(void*) )
+ {
+ *dp++ = *sp++;
+ count -= sizeof(void*);
+ }
+ dst = (uintptr_t)dp; src = (uintptr_t)sp;
+ for( ; count; count -- )
+ *(char*)dst++ = *(char*)src++;
+ }
+
+ return __dest;
}
/**
*/
EXPORT void *memmove(void *dest, const void *src, size_t count)
{
- char *sp = (char *)src;
- char *dp = (char *)dest;
- // Check if corruption will happen
- if( (unsigned int)dest > (unsigned int)src && (unsigned int)dest < (unsigned int)src+count )
+ char *sp = (char *)src;
+ char *dp = (char *)dest;
+ // Check if the areas overlap
+ if( (intptr_t)dest > (intptr_t)src && (intptr_t)dest < (intptr_t)src+count )
for(;count--;) dp[count] = sp[count];
else
- for(;count--;) *dp++ = *sp++;
- return dest;
+ for(;count--;) *dp++ = *sp++;
+ return dest;
}
/**
*/
EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
{
+ const unsigned char *p1 = mem1, *p2 = mem2;
while(count--)
{
- if( *(unsigned char*)mem1 != *(unsigned char*)mem2 )
- return *(unsigned char*)mem1 - *(unsigned char*)mem2;
- mem1 ++;
- mem2 ++;
+ if( *p1 != *p2 )
+ return *p1 - *p2;
+ p1 ++;
+ p2 ++;
}
return 0;
}
* \param value Value to find
* \param num Size of memory area to check
*/
-EXPORT void *memchr(void *ptr, int value, size_t num)
+EXPORT void *memchr(const void *ptr, int value, size_t num)
{
while(num--)
{
- if( *(unsigned char*)ptr == (unsigned char)value )
- return ptr;
+ if( *(const unsigned char*)ptr == (unsigned char)value )
+ return (void*)ptr;
ptr ++;
}
return NULL;
}
+
+EXPORT size_t strcspn(const char *haystack, const char *reject)
+{
+ size_t ret = 0;
+ int i;
+ while( *haystack )
+ {
+ for( i = 0; reject[i] && reject[i] == *haystack; i ++ );
+
+ if( reject[i] ) return ret;
+ ret ++;
+ }
+ return ret;
+}
+
+EXPORT size_t strspn(const char *haystack, const char *accept)
+{
+ size_t ret = 0;
+ int i;
+ while( *haystack )
+ {
+ for( i = 0; accept[i] && accept[i] == *haystack; i ++ );
+
+ if( !accept[i] ) return ret;
+ ret ++;
+ }
+ return ret;
+}