X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fstring.c;h=09481d8605ae40c817005537de47902b386f51ae;hb=230612b2efeeb769f1d96193ec01b10bd36d9873;hp=d8d08721f9def9f4fa2e613778288a1f0bfe99fa;hpb=f194730e75d6d3681e5f99a4efed1616fd1ea738;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c index d8d08721..09481d86 100644 --- a/Usermode/Libraries/libc.so_src/string.c +++ b/Usermode/Libraries/libc.so_src/string.c @@ -2,30 +2,30 @@ * AcessOS Basic C Library * string.c */ -#include +//#include #include #include #include #include "lib.h" +#include /** * \fn EXPORT int strcmp(const char *s1, const char *s2) * \brief Compare two strings */ -EXPORT int strcmp(const char *s1, const char *s2) +EXPORT int strcmp(const char *_s1, const char *_s2) { - while(*s1 && *s1 == *s2) { - s1++; s2++; - } - return (int)*s1 - (int)*s2; + return strncmp(_s1, _s2, SIZE_MAX); } /** - * \fn EXPORT int strncmp(const char *s1, const char *s2) - * \brief Compare two strings + * \fn EXPORT int strncmp(const char *s1, const char *s2, size_t n) + * \brief Compare two strings, stopping after n characters */ -EXPORT int strncmp(const char *s1, const char *s2, size_t n) +EXPORT int strncmp(const char *_s1, const char *_s2, size_t n) { + const unsigned char* s1 = (const unsigned char*)_s1; + const unsigned char* s2 = (const unsigned char*)_s2; while(n && *s1 && *s1 == *s2) { s1++; s2++; @@ -37,23 +37,31 @@ EXPORT int strncmp(const char *s1, const char *s2, size_t n) return (int)*s1 - (int)*s2; } -EXPORT int strcasecmp(const char *s1, const char *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; + return strncasecmp(_s1, _s2, SIZE_MAX); } -EXPORT int strncasecmp(const char *s1, const char *s2, size_t n) +EXPORT int strncasecmp(const char *_s1, const char *_s2, size_t n) { - int rv = 0; - if( n == 0 ) return 0; - while(n -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') { - s1++; s2++; + const unsigned char* s1 = (const unsigned char*)_s1; + const unsigned char* s2 = (const unsigned char*)_s2; + while( n-- && *s1 && *s2 ) + { + if( *s1 != *s2 ) + { + int rv; + rv = toupper(*s1) - toupper(*s2); + if(rv != 0) + return rv; + rv = tolower(*s1) - tolower(*s2); + if(rv != 0) + return rv; + } + s1 ++; + s2 ++; } - return rv; + return 0; } /** @@ -79,8 +87,13 @@ EXPORT char *strcpy(char *dst, const char *src) EXPORT char *strncpy(char *dst, const char *src, size_t num) { char *to = dst; - while(*src && num--) *to++ = *src++; - *to = '\0'; + while(num --) + { + if(*src) + *to++ = *src++; + else + *to++ = '\0'; + } return dst; } @@ -100,14 +113,27 @@ 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 */ EXPORT size_t strlen(const char *str) { - size_t retval; - for(retval = 0; *str != '\0'; str++, retval++); - return retval; + size_t len = 0; + while(str[len] != '\0') + len ++; + return len; } /** @@ -117,8 +143,9 @@ EXPORT size_t strlen(const char *str) */ EXPORT size_t strnlen(const char *str, size_t maxlen) { - size_t len; - for( len = 0; maxlen -- && *str; str ++, len ++ ); + size_t len = 0; + while( len < maxlen && str[len] != '\0' ) + len ++; return len; } @@ -157,14 +184,16 @@ EXPORT char *strndup(const char *str, size_t maxlen) /** * \fn EXPORT char *strchr(char *str, int character) * \brief Locate a character in a string + * \note The terminating NUL is part of the string */ -EXPORT char *strchr(const char *str, int character) +EXPORT char *strchr(const char *_str, int character) { - for(;*str;str++) + const unsigned char* str = (const unsigned char*)_str; + do { - if(*str == character) + if( *str == character ) return (char*)str; - } + } while( *str++ ); return NULL; } @@ -172,15 +201,15 @@ EXPORT char *strchr(const char *str, int character) * \fn EXPORT char *strrchr(char *str, int character) * \brief Locate the last occurance of a character in a string */ -EXPORT char *strrchr(const char *str, int character) +EXPORT char *strrchr(const char *_str, int character) { - int i; - i = strlen(str)-1; - while(i--) + const unsigned char* str = (const unsigned char*)_str; + size_t i = strlen(_str); + do { if(str[i] == character) return (void*)&str[i]; - } + } while( i -- ); return NULL; } @@ -188,13 +217,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; } @@ -264,20 +293,31 @@ EXPORT void *memcpy(void *__dest, const void *__src, size_t count) return __dest; } +// TODO: memccpy (POSIX defined) + /** * \fn EXPORT void *memmove(void *dest, const void *src, size_t count) * \brief Copy data in memory, avoiding overlap problems */ EXPORT void *memmove(void *dest, const void *src, size_t count) { - char *sp = (char *)src; + const char *sp = (const 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 + 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; } @@ -294,7 +334,7 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count) while(count--) { if( *p1 != *p2 ) - return *p1 - *p2; + return (int)*p1 - (int)*p2; p1 ++; p2 ++; } @@ -310,11 +350,12 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count) */ EXPORT void *memchr(const void *ptr, int value, size_t num) { + const unsigned char* buf = ptr; while(num--) { - if( *(const unsigned char*)ptr == (unsigned char)value ) - return (void*)ptr; - ptr ++; + if( *buf == (unsigned char)value ) + return (void*)buf; + buf ++; } return NULL; } @@ -322,12 +363,13 @@ EXPORT void *memchr(const void *ptr, int value, size_t num) 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; + for( int i = 0; reject[i]; i ++ ) + { + if( reject[i] == *haystack ) + return ret; + } ret ++; } return ret; @@ -336,13 +378,60 @@ EXPORT size_t strcspn(const char *haystack, const char *reject) 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; + for( int i = 0; accept[i]; i ++ ) + { + if( accept[i] != *haystack ) + return ret; + } ret ++; } 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; + } + 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; +} +