Merge branch 'master' of git://localhost/acess2
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / string.c
index e85356d..d8d0872 100644 (file)
@@ -5,6 +5,7 @@
 #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;
 }
 
+/**
+ * \fn EXPORT int strncmp(const char *s1, const char *s2)
+ * \brief Compare two strings
+ */
+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 -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') {
+               s1++; s2++;
+       }
+       return rv;
+}
+
 /**
  * \fn EXPORT char *strcpy(char *dst, const char *src)
  * \brief Copy a string to another
@@ -64,27 +101,25 @@ 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;
 }
 
 /**
- * \fn EXPORT int strncmp(const char *s1, const char *s2, size_t len)
- * \brief Compare two strings with a limit
+ * \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 int strncmp(const char *s1, const char *s2, size_t len)
+EXPORT size_t strnlen(const char *str, size_t maxlen)
 {
-       while(--len && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
-               s1++; s2++;
-       }
-       return (int)*s1 - (int)*s2;
+       size_t  len;
+       for( len = 0; maxlen -- && *str; str ++, len ++ );
+       return len;
 }
 
 /**
@@ -123,11 +158,12 @@ EXPORT char *strndup(const char *str, size_t maxlen)
  * \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;
 }
@@ -136,13 +172,14 @@ EXPORT char *strchr(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(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;
 }
@@ -155,12 +192,11 @@ EXPORT char *strstr(char *str1, const char *str2)
 {
        const char      *test = str2;
        
-       while(*str1)
+       for(;*str1;str1++)
        {
                if(*test == '\0')       return str1;
                if(*str1 == *test)      test++;
                else    test = str2;
-               str1 ++;
        }
        return NULL;
 }
@@ -181,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;
 }
 
 /**
@@ -195,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( (unsigned int)dest > (unsigned int)src && (unsigned int)dest < (unsigned int)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;
 }
 
 /**
@@ -214,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;
 }
@@ -231,13 +308,41 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
  * \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;
+}

UCC git Repository :: git.ucc.asn.au