* AcessOS Basic C Library
* string.c
*/
-#include <acess/sys.h>
+//#include <acess/sys.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "lib.h"
+#include <string.h>
/**
* \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++;
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;
}
/**
EXPORT size_t strnlen(const char *str, size_t maxlen)
{
size_t len;
- for( len = 0; maxlen -- && *str; str ++, len ++ );
+ for( len = 0; maxlen -- && *str; str ++, len ++ )
+ ;
return len;
}
* \fn EXPORT char *strchr(char *str, int character)
* \brief Locate a character in a string
*/
-EXPORT char *strchr(const char *str, int character)
+EXPORT char *strchr(const char *_str, int character)
{
+ const unsigned char* str = (const unsigned char*)_str;
for(;*str;str++)
{
- if(*str == character)
+ 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(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;
+ for( int i = strlen(_str); i--; )
{
if(str[i] == character)
return (void*)&str[i];
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;
}
while(count--)
{
if( *p1 != *p2 )
- return *p1 - *p2;
+ return (int)*p1 - (int)*p2;
p1 ++;
p2 ++;
}
*/
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;
}
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;
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;
+}
+