diff --git a/libmaxsi/c/hsrc/string.h b/libmaxsi/c/hsrc/string.h index a0b734c4..a65b6e54 100644 --- a/libmaxsi/c/hsrc/string.h +++ b/libmaxsi/c/hsrc/string.h @@ -38,10 +38,14 @@ void* memcpy(void* restrict, const void* restrict, size_t); void* memset(void*, int, size_t); char* strcat(char* restrict, const char* restrict); int strcmp(const char*, const char*); +size_t strcspn(const char*, const char*); char* strcpy(char* restrict, const char* restrict); char* strerror(int); size_t strlen(const char*); int strncmp(const char*, const char*, size_t); +size_t strspn(const char*, const char*); +char* strtok(char* restrict, const char* restrict); +char* strtok_r(char* restrict, const char* restrict, char** restrict); /* TODO: These are not implemented in libmaxsi/sortix yet. */ #ifndef SORTIX_UNIMPLEMENTED @@ -53,7 +57,6 @@ char* stpncpy(char* restrict, const char* restrict, size_t); char* strchr(const char*, int); int strcoll(const char*, const char*); int strcoll_l(const char*, const char*, locale_t); -size_t strcspn(const char*, const char*); char* strdup(const char*); char* strerror_l(int, locale_t); int strerror_r(int, char*, size_t); @@ -64,10 +67,7 @@ size_t strnlen(const char*, size_t); char* strpbrk(const char*, const char*); char* strrchr(const char*, int); char* strsignal(int); -size_t strspn(const char*, const char*); char* strstr(const char*, const char*); -char* strtok(char* restrict, const char* restrict); -char* strtok_r(char* restrict, const char* restrict, char** restrict); size_t strxfrm(char* restrict, const char* restrict, size_t); size_t strxfrm_l(char* restrict, const char* restrict, size_t, locale_t); #endif diff --git a/libmaxsi/hsrc/string.h b/libmaxsi/hsrc/string.h index 37b447cb..c00bb4d6 100644 --- a/libmaxsi/hsrc/string.h +++ b/libmaxsi/hsrc/string.h @@ -29,13 +29,18 @@ namespace Maxsi { namespace String { - const char ASCII_ESCAPE = 27; + // TODO: Remove this once. Use \e instead. + const char ASCII_ESCAPE = 27; size_t Length(const char* String); + size_t Accept(const char* str, const char* accept); + size_t Reject(const char* str, const char* reject); char* Clone(const char* Source); char* Combine(size_t NumParameters, ...); char* Copy(char* Dest, const char* Src); char* Cat(char* Dest, const char* Src); + char* Tokenize(char* str, const char* delim); + char* TokenizeR(char* str, const char* delim, char** saveptr); int Compare(const char* A, const char* B); int CompareN(const char* A, const char* B, size_t MaxLength); bool StartsWith(const char* Haystack, const char* Needle); diff --git a/libmaxsi/string.cpp b/libmaxsi/string.cpp index 14abe3c1..550c6470 100644 --- a/libmaxsi/string.cpp +++ b/libmaxsi/string.cpp @@ -98,6 +98,63 @@ namespace Maxsi return 0; } + DUAL_FUNCTION(size_t, strspn, Accept, (const char* str, const char* accept)) + { + size_t acceptlen = 0; + while ( accept[acceptlen] ) { acceptlen++; } + for ( size_t result = 0; true; result++ ) + { + char c = str[result]; + if ( !c ) { return result; } + bool matches = false; + for ( size_t i = 0; i < acceptlen; i++ ) + { + if ( str[result] != accept[i] ) { continue; } + matches = true; + break; + } + if ( !matches ) { return result; } + } + } + + DUAL_FUNCTION(size_t, strcspn, Reject, (const char* str, const char* reject)) + { + size_t rejectlen = 0; + while ( reject[rejectlen] ) { rejectlen++; } + for ( size_t result = 0; true; result++ ) + { + char c = str[result]; + if ( !c ) { return result; } + bool matches = false; + for ( size_t i = 0; i < rejectlen; i++ ) + { + if ( str[result] != reject[i] ) { continue; } + matches = true; + break; + } + if ( matches ) { return result; } + } + } + + DUAL_FUNCTION(char*, strtok_r, TokenizeR, (char* str, const char* delim, char** saveptr)) + { + if ( !str && !*saveptr ) { return NULL; } + if ( !str ) { str = *saveptr; } + str += Accept(str, delim); // Skip leading + if ( !*str ) { return NULL; } + size_t amount = Reject(str, delim); + if ( str[amount] ) { *saveptr = str + amount + 1; } + else { *saveptr = NULL; } + str[amount] = '\0'; + return str; + } + + DUAL_FUNCTION(char*, strtok, TokenizeR, (char* str, const char* delim)) + { + static char* lasttokensaveptr = NULL; + return TokenizeR(str, delim, &lasttokensaveptr); + } + bool StartsWith(const char* haystack, const char* needle) { return CompareN(haystack, needle, Length(needle)) == 0;