fixed and reworked cutils_memmem() and added more tests for string_find_str()
Msrc/extensions.c
| @@ -68,27 +68,59 @@ char* cutil_strndup(const char* s, size_t n) | |||
|---|---|---|---|
| 68 | 68 | ||
| 69 | 69 | bool cutil_memmem(const void* haystack, size_t haystacklen, const void* needle, size_t needlelen, size_t* pos) | |
| 70 | 70 | { | |
| 71 | - | size_t i, j; | |
| 71 | + | size_t newoffset, offset = 0, i, j; | |
| 72 | 72 | const byte* haystackb = haystack; | |
| 73 | 73 | const byte* needleb = needle; | |
| 74 | + | byte* start; | |
| 75 | + | bool newoffset_set = false; | |
| 74 | 76 | ||
| 75 | 77 | if(needlelen == 0) | |
| 78 | + | { | |
| 79 | + | *pos = 0; | |
| 76 | 80 | return true; | |
| 81 | + | } | |
| 77 | 82 | ||
| 78 | - | if(HEDLEY_UNLIKELY((haystacklen == 0 && needlelen != 0 )|| haystacklen < needlelen)) | |
| 83 | + | if(HEDLEY_UNLIKELY((haystacklen == 0 && needlelen > 0 )|| haystacklen < needlelen)) | |
| 79 | 84 | return false; | |
| 80 | - | //TODO: use memchr as base search | |
| 81 | - | for(i = 0; i < haystacklen; i++) | |
| 85 | + | ||
| 86 | + | CUTIL_LOOP | |
| 82 | 87 | { | |
| 83 | - | for(j = 0, *pos = i; j < needlelen && i < haystacklen; j++, i++) | |
| 88 | + | start = memchr(haystackb+offset, needleb[0], haystacklen-offset); | |
| 89 | + | if(!start) | |
| 90 | + | { | |
| 91 | + | return false; | |
| 92 | + | } else if(needlelen == 1) { | |
| 93 | + | *pos = (size_t)(start-haystackb); | |
| 94 | + | return true; | |
| 95 | + | } | |
| 96 | + | ||
| 97 | + | for(i = (size_t)(start-haystackb+1), j = 1; i < haystacklen && j < needlelen; i++, j++) | |
| 84 | 98 | { | |
| 99 | + | if(!newoffset_set && haystackb[i] == needleb[0]) | |
| 100 | + | { | |
| 101 | + | newoffset = i; | |
| 102 | + | newoffset_set = true; | |
| 103 | + | } | |
| 104 | + | ||
| 85 | 105 | if(haystackb[i] != needleb[j]) | |
| 106 | + | { | |
| 86 | 107 | break; | |
| 87 | - | else if(j == needlelen-1) | |
| 108 | + | } else if(j == needlelen-1) { | |
| 109 | + | *pos = (size_t)(start-haystackb); | |
| 88 | 110 | return true; | |
| 111 | + | } | |
| 112 | + | } | |
| 113 | + | ||
| 114 | + | if(newoffset_set) | |
| 115 | + | { | |
| 116 | + | offset = newoffset; | |
| 117 | + | newoffset_set = false; | |
| 118 | + | } else { | |
| 119 | + | offset = i; | |
| 89 | 120 | } | |
| 90 | 121 | } | |
| 91 | 122 | ||
| 123 | + | ||
| 92 | 124 | return false; | |
| 93 | 125 | } | |
| 94 | 126 | ||
Msrc/test.c
| @@ -108,11 +108,44 @@ static void test_string(void) | |||
|---|---|---|---|
| 108 | 108 | delete_string(string2); | |
| 109 | 109 | delete_string(string); | |
| 110 | 110 | ||
| 111 | - | string = from_cstring("abcd", truth); | |
| 112 | - | string2 = from_cstring("cd", truth); | |
| 111 | + | string = from_cstring("abababcd", truth); | |
| 112 | + | string2 = from_cstring("ababcd", truth); | |
| 113 | 113 | assert(string_find_str(string, string2, &tmp)); | |
| 114 | 114 | assert(tmp == 2); | |
| 115 | + | delete_string(string2); | |
| 116 | + | delete_string(string); | |
| 117 | + | ||
| 118 | + | string = from_cstring("abab", truth); | |
| 119 | + | string2 = from_cstring("abc", truth); | |
| 120 | + | assert(!string_find_str(string, string2, &tmp)); | |
| 121 | + | delete_string(string2); | |
| 122 | + | delete_string(string); | |
| 123 | + | ||
| 124 | + | string = from_cstring("abababcd", truth); | |
| 125 | + | string2 = from_cstring("ab", truth); | |
| 126 | + | assert(string_find_str(string, string2, &tmp)); | |
| 127 | + | assert(tmp == 0); | |
| 128 | + | delete_string(string2); | |
| 129 | + | delete_string(string); | |
| 115 | 130 | ||
| 131 | + | string = from_cstring("ABC ABCDAB ABCDABCDABDE", truth); | |
| 132 | + | string2 = from_cstring("ABCDABD", truth); | |
| 133 | + | assert(string_find_str(string, string2, &tmp)); | |
| 134 | + | assert(tmp == 15); | |
| 135 | + | delete_string(string2); | |
| 136 | + | delete_string(string); | |
| 137 | + | ||
| 138 | + | string = from_cstring("asdasdasdasdp", truth); | |
| 139 | + | string2 = from_cstring("p", truth); | |
| 140 | + | assert(string_find_str(string, string2, &tmp)); | |
| 141 | + | assert(tmp == 12); | |
| 142 | + | delete_string(string2); | |
| 143 | + | delete_string(string); | |
| 144 | + | ||
| 145 | + | string = from_cstring("asdpsdasdasdpa", truth); | |
| 146 | + | string2 = from_cstring("pa", truth); | |
| 147 | + | assert(string_find_str(string, string2, &tmp)); | |
| 148 | + | assert(tmp == 12); | |
| 116 | 149 | delete_string(string2); | |
| 117 | 150 | delete_string(string); | |
| 118 | 151 | ||
| @@ -385,3 +418,4 @@ int main(int argc, char** argv) | |||
|---|---|---|---|
| 385 | 418 | ||
| 386 | 419 | return 0; | |
| 387 | 420 | } | |
| 421 | + | /* TODO: split up test files */ | |