X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fstring.c;h=0757c24ad3ee46432d3cc7f1232017dfe06cb968;hb=6fbf6b93bec9b8b5bd6d7c683eefb0ebed8dff77;hp=ceafd99b2b55f4f0965f8c96bd2ea75acac757e5;hpb=c1f0f7a89e019bfb3c0dc908820118e10b83790b;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c index ceafd99b..0757c24a 100644 --- a/Usermode/Libraries/libc.so_src/string.c +++ b/Usermode/Libraries/libc.so_src/string.c @@ -7,6 +7,7 @@ #include #include #include "lib.h" +#include /** * \fn EXPORT int strcmp(const char *s1, const char *s2) @@ -14,7 +15,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; @@ -26,7 +27,7 @@ EXPORT int strcmp(const char *s1, const char *s2) */ EXPORT int strncmp(const char *s1, const char *s2, size_t n) { - while(n && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') + while(n && *s1 && *s1 == *s2) { s1++; s2++; n --; @@ -100,6 +101,18 @@ EXPORT char *strcat(char *dst, const char *src) return dst; } +EXPORT char *strncat(char *dst, const char *src, size_t n) +{ + char *to = dst; + // Find the end + while(*to) to++; + // Copy + while(*src && n--) *to++ = *src++; + // End string + *to = '\0'; + return dst; +} + /** * \brief Get the length of a string */ @@ -188,13 +201,13 @@ EXPORT char *strrchr(const char *str, int character) * \fn EXPORT char *strstr(char *str1, const char *str2) * \brief Search a \a str1 for the first occurance of \a str2 */ -EXPORT char *strstr(char *str1, const char *str2) +EXPORT char *strstr(const char *str1, const char *str2) { const char *test = str2; for(;*str1;str1++) { - if(*test == '\0') return str1; + if(*test == '\0') return (char*)str1; if(*str1 == *test) test++; else test = str2; } @@ -217,12 +230,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; } /** @@ -231,14 +283,24 @@ 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]; - else - for(;count--;) *dp++ = *sp++; - return dest; + const char *sp = (const char *)src; + char *dp = (char *)dest; + // Check if the areas overlap + if( sp >= dp+count ) + memcpy(dest, src, count); + else if( dp >= sp+count ) + memcpy(dest, src, count); + else { + if( sp < dp ) { + while(count--) + dp[count] = sp[count]; + } + else { + while(count--) + *dp++ = *sp++; + } + } + return dest; } /** @@ -250,12 +312,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; } @@ -305,3 +368,48 @@ EXPORT size_t strspn(const char *haystack, const char *accept) } return ret; } + +EXPORT char *strpbrk(const char *haystack, const char *accept) +{ + while( *haystack ) + { + for( int i = 0; accept[i]; i ++ ) + { + if( accept[i] == *haystack ) + return (char*)haystack; + } + } + return NULL; +} + +char *strtok(char *str, const char *delim) +{ + static char *__saveptr; + return strtok_r(str, delim, &__saveptr); +} +char *strtok_r(char *str, const char *delim, char **saveptr) +{ + char *pos = (str ? str : *saveptr); + + while( strchr(delim, *pos) ) + pos ++; + + if( *pos == '\0' ) + return NULL; + + char *ret = pos; + while( !strchr(delim, *pos) ) + pos ++; + + // Cap the returned string + // - If we're at the end of the original string, don't shift pos + if( *pos != '\0' ) { + *pos = '\0'; + pos ++; + } + + *saveptr = pos; + + return ret; +} +