diff --git a/src/Hashtable/Hashtable.c b/src/Hashtable/Hashtable.c index ae84083..9c8fe15 100644 --- a/src/Hashtable/Hashtable.c +++ b/src/Hashtable/Hashtable.c @@ -86,7 +86,7 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key){ u32 arlen=Autoarr_length(ar); for(u32 i=0;ikey)) return &p->value; + if(cptr_equals(key,p->key)) return &p->value; } return NULL; } @@ -96,7 +96,7 @@ Unitype Hashtable_get(Hashtable* ht, char* key){ u32 arlen=Autoarr_length(ar); for(u32 i=0;i // returns length of char buffer (without \0) -u32 cptr_length(char* str){ - u32 len=0; - while(*(str++)) len++; - return len; +u32 cptr_length(const char* str){ + const char *const str_first=str; + while(*str) + str++; + return str-str_first; } // allocates new char[] and copies src there -char* cptr_copy(char* src){ +char* cptr_copy(const char* src){ u32 len=cptr_length(src)+1; char* dst=malloc(len); while(len--!=0) @@ -17,16 +19,6 @@ char* cptr_copy(char* src){ return dst; } -// compares two char buffers, NullPtr-friendly -bool cptr_compare(char* key0, char* key1){ - if(!key0) return key1 ? false : true; - if(!key1) return false; - while(*key0&&*key1) - if(*key0++ != *key1++) - return false; - return true; -} - // multiplies char n times char* char_multiply(char c, u32 n){ char* rez=malloc(n+1); @@ -36,63 +28,105 @@ char* char_multiply(char c, u32 n){ return rez; } -bool cptr_startsWith(char* ptr, char* fragment){ - for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment) - if(cs!=cf) return false; - return true; +bool cptr_equals(const char* key0, const char* key1){ + char c0=*key0; + char c1=*key1; + bool eq=c0==c1; + while(c0 && c1 && eq) { + c0=*++key0; + c1=*++key1; + eq=c0==c1; + } + return eq; } -bool cptr_endsWith(char* ptr, char* fragment){ - ptr+=cptr_length(ptr)-cptr_length(fragment); - for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment) - if(cs!=cf) return false; - return true; +bool cptr_startsWith(const char* src, const char* fragment){ + char c0=*src; + char c1=*fragment; + bool eq=c0==c1 && c0 !=0 && c1!=0; + while(c0 && c1 && eq) { + c0=*++src; + c1=*++fragment; + eq=c0==c1; + if(c1==0) + return true; + } + return eq; } -u32 cptr_indexOf(char* ptr, char* fragment){ - char sc=*ptr; - for(u32 si=0, fi=0; sc!='\0'; si++){ - sc=ptr[si]; - if(sc==fragment[fi]){ - fi++; - if(fragment[fi]==0) - return si-fi+1; - } - else fi=0; +bool cptr_endsWith(const char* src, const char* fragment){ + u32 src_len=cptr_length(src); + u32 fr_len=cptr_length(fragment); + if(src_len=0; si--){ - sc=ptr[si]; - if(sc==fragment[fi]){ - if(fi==0) - return si; - fi--; - } - else fi=fi_last; - } - return -1; -} -u32 cptr_lastIndexOfChar(char* ptr, char fragment){ - char sc; - for(i32 si=cptr_length(ptr)-1; si>=0; si--){ - sc=ptr[si]; - if(sc==fragment){ + +i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength){ + char sc=*src; + if(sc==0 || fragment==0) + return -1; + i32 len=cptr_length(src); + if(startIndex==(u32)-1) + startIndex=len-1; + for(u32 si=startIndex; si<(u32)-1 && si!=len-1-seekLength; si--){ + sc=src[si]; + if(sc==fragment) return si; - } } return -1; } @@ -123,7 +157,7 @@ char* __cptr_concat(u32 n, ...){ // allocating memory for output value char* totality=malloc(totalLength+1); - const char* output=totality; + char* output=totality; totality[totalLength]=0; // copying content of all strings to rezult @@ -137,7 +171,7 @@ char* __cptr_concat(u32 n, ...){ return output; } -char* cptr_toLower(char* src) { +char* cptr_toLower(const char* src) { u32 length=cptr_length(src); char *p=malloc(length+1); p[length]=0; @@ -146,7 +180,7 @@ char* cptr_toLower(char* src) { return p; } -char* cptr_toUpper(char* src) { +char* cptr_toUpper(const char* src) { u32 length=cptr_length(src); char *p=malloc(length+1); p[length]=0; @@ -154,3 +188,28 @@ char* cptr_toUpper(char* src) { p[i]=toupper(src[i]); return p; } + +char* cptr_replaceChar(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){ + char* rzlt=cptr_copy(src); + char c=*src; + for(u32 i=startIndex; i inclusion in or -1 if not found +i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength); -bool cptr_endsWith(char* ptr, char* fragment); +/// @param startIndex -1 ... src length +/// @param seekLength 0 ... -1 +/// @return pos of first inclusion in or -1 if not found +i32 cptr_seekReverse(const char* src, const char* fragment, u32 startIndex, u32 seekLength); + +/// @param startIndex 0 ... src length +/// @param seekLength 0 ... -1 +/// @return pos of first inclusion in or -1 if not found +i32 cptr_seekChar(const char* src, char fragment, u32 startIndex, u32 seekLength); + +/// @param startIndex -1 ... src length +/// @param seekLength 0 ... -1 +/// @return pos of first inclusion in or -1 if not found +i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength); /// @brief search for in /// @return index of first inclusion or -1 if not found -u32 cptr_indexOf(char* ptr, char* fragment); +static inline i32 cptr_indexOf(const char* src, const char* fragment) +{ return cptr_seek(src, fragment, 0, -1); } + /// @brief search for in /// @return index of first inclusion or -1 if not found -u32 cptr_indexOfChar(char* ptr, char fragment); -/// @brief search for in -/// @return index of last inclusion or -1 if not found -u32 cptr_lastIndexOf(char* ptr, char* fragment); -/// @brief search for in -/// @return index of last inclusion or -1 if not found -u32 cptr_lastIndexOfChar(char* ptr, char fragment); +static inline i32 cptr_indexOfChar(const char* src, char fragment) +{ return cptr_seekChar(src, fragment, 0, -1); } -static inline bool cptr_contains(char* ptr, char* fragment){ - // if(cptr_indexOf(ptr, fragment)==-1) - // return false; - // return true; - return cptr_indexOf(ptr, fragment) +1; +/// @brief search for in +/// @return index of last inclusion or -1 if not found +static inline i32 cptr_lastIndexOf(const char* src, const char* fragment) +{ return cptr_seekReverse(src, fragment, -1, -1); } + +/// @brief search for in +/// @return index of last inclusion or -1 if not found +static inline i32 cptr_lastIndexOfChar(const char* src, char fragment) +{ return cptr_seekCharReverse(src, fragment, -1, -1); } + + +static inline bool cptr_contains(const char* src, const char* fragment){ + return cptr_seek(src, fragment, 0, -1) +1; } void memcopy(void* from, void* to, u32 size); @@ -47,8 +71,17 @@ void memcopy(void* from, void* to, u32 size); char* __cptr_concat(u32 n, ...); #define cptr_concat(STR...) __cptr_concat(count_args(STR), STR) -char* cptr_toLower(char* src); -char* cptr_toUpper(char* src); +char* cptr_toLower(const char* src); +char* cptr_toUpper(const char* src); + +/// @param startIndex 0 ... src length +/// @param seekLength 0 ... -1 +/// @return with replaced by or empty cstring if not found +char* cptr_replace(const char* src, char* str_old, char* str_new, u32 startIndex, u32 seekLength); +/// @param startIndex 0 ... src length +/// @param seekLength 0 ... -1 +/// @return with replaced by or empty cstring if not found +char* cptr_replaceChar(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength); #if __cplusplus } diff --git a/tests/test_cptr.c b/tests/test_cptr.c new file mode 100644 index 0000000..ff05f4e --- /dev/null +++ b/tests/test_cptr.c @@ -0,0 +1,161 @@ +#include "tests.h" + +/* + TODO +test cptr_seek... +test cptr_...indexOf... +test cptr_replace... + +cases: +*/ + +const char* strings[]={ + "", + "abab", + "ab_ab", + "abab_", + "_abab", + "_ab_ab_", + "_ab_ab", + "_abab_", + "_ab_ab_", + "str_not_containing_a_b", + "" +}; + +#define test_startsWith(str, fragm) \ + kprintf("\e[37m'"str"' starts with '"fragm"'"); \ + if(cptr_startsWith(str,fragm)) kprintf("\e[92m true\n"); \ + else { kprintf("\e[91m false\n"); throw(ERR_UNEXPECTEDVAL); } + +#define test_DoesntStartWith(str, fragm) \ + kprintf("\e[37m'"str"' doesnt start with '"fragm"'"); \ + if(!cptr_startsWith(str,fragm)) kprintf("\e[92m true\n"); \ + else { kprintf("\e[91m false\n"); throw(ERR_UNEXPECTEDVAL); } + +#define test_endsWith(str, fragm) \ + kprintf("\e[37m'"str"' ends with '"fragm"'"); \ + if(cptr_endsWith(str,fragm)) kprintf("\e[92m true\n"); \ + else { kprintf("\e[91m false\n"); throw(ERR_UNEXPECTEDVAL); } + +#define test_DoesntEndWith(str, fragm) \ + kprintf("\e[37m'"str"' doesnt end with '"fragm"'"); \ + if(!cptr_endsWith(str,fragm)) kprintf("\e[92m true\n"); \ + else { kprintf("\e[91m false\n"); throw(ERR_UNEXPECTEDVAL); } + +#define test_seekChar(str, fragm, start, count, expected) \ + kprintf("\e[37mseek "#fragm" in '"str"' startIndex "#start" count "#count); \ + pos=cptr_seekChar(str, fragm, start, count); \ + if(pos == expected) kprintf("\e[92m %i\n", pos); \ + else { kprintf("\e[91m %i\n", pos); throw(ERR_UNEXPECTEDVAL); } + +#define test_seekCharReverse(str, fragm, start, count, expected) \ + kprintf("\e[37mseek reverse "#fragm" in '"str"' startIndex "#start" count "#count); \ + pos=cptr_seekCharReverse(str, fragm, start, count); \ + if(pos == expected) kprintf("\e[92m %i\n", pos); \ + else { kprintf("\e[91m %i\n", pos); throw(ERR_UNEXPECTEDVAL); } + +#define test_seek(str, fragm, start, count, expected) \ + kprintf("\e[37mseek '"fragm"' in '"str"' startIndex "#start" count "#count); \ + pos=cptr_seek(str, fragm, start, count); \ + if(pos == expected) kprintf("\e[92m %i\n", pos); \ + else { kprintf("\e[91m %i\n", pos); throw(ERR_UNEXPECTEDVAL); } + +#define test_seekReverse(str, fragm, start, count, expected) \ + kprintf("\e[37mseek reverse '"fragm"' in '"str"' startIndex "#start" count "#count); \ + pos=cptr_seekReverse(str, fragm, start, count); \ + if(pos == expected) kprintf("\e[92m %i\n", pos); \ + else { kprintf("\e[91m %i\n", pos); throw(ERR_UNEXPECTEDVAL); } + +const int strings_len=sizeof(strings)/sizeof(strings[0]); + +void test_cptr(){ + // optime(__func__,1, + kprintf("\e[96m-------------[test_cptr]--------------\n"); + // compare + kprintf("\e[94m--------------[compare]---------------\n"); + for(int i=0; i