X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fstring.c;h=d8d08721f9def9f4fa2e613778288a1f0bfe99fa;hb=04a050f42807686dc119838c82372409246d55bb;hp=607039eddb970ff61693caf95b907a8802c86b58;hpb=7681237dd0061c95dd4b22ca1b5c8c3c8b8fae2e;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c index 607039ed..d8d08721 100644 --- a/Usermode/Libraries/libc.so_src/string.c +++ b/Usermode/Libraries/libc.so_src/string.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "lib.h" /** @@ -13,7 +14,7 @@ */ 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; @@ -25,11 +26,34 @@ EXPORT int strcmp(const char *s1, const char *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; } /** @@ -77,17 +101,27 @@ EXPORT char *strcat(char *dst, const char *src) } /** - * \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 @@ -183,12 +217,51 @@ EXPORT void *memset(void *dest, int val, size_t num) * \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; } /** @@ -197,14 +270,15 @@ EXPORT void *memcpy(void *dest, const void *src, size_t count) */ 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( (intptr_t)dest > (intptr_t)src && (intptr_t)dest < (intptr_t)src+count ) - for(;count--;) dp[count] = sp[count]; + char *sp = (char *)src; + char *dp = (char *)dest; + // Check if the areas overlap + if( (uintptr_t)src < (uintptr_t)dest && (uintptr_t)dest < (uintptr_t)src+count ) + for(;count--;) + dp[count] = sp[count]; else - for(;count--;) *dp++ = *sp++; - return dest; + memcpy(dest, src, count); + return dest; } /** @@ -216,12 +290,13 @@ EXPORT void *memmove(void *dest, const void *src, size_t count) */ 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; } @@ -243,3 +318,31 @@ EXPORT void *memchr(const void *ptr, int value, size_t num) } 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; +}