/* See LICENSE file for copyright and license details. */ #include "common.h" #ifndef TEST void * libsimple_memmem(const void *hay_, size_t hayn, const void *sub_, size_t subn) { const unsigned char *hay = hay_; const unsigned char *sub = sub_; size_t *next, i, j; if (!subn) return REMOVE_CONST(hay, unsigned char *); if (hayn < subn) return NULL; if (subn == 1) return memchr(hay, *sub, hayn); next = alloca((subn + 1U) * sizeof(*next)); i = 0, j = SIZE_MAX; goto beginning; for (; i < subn; i++, j++) { if (sub[i] == sub[j]) { next[i] = next[j]; } else { beginning: next[i] = j; while (j != SIZE_MAX && sub[i] != sub[j]) j = next[j]; } } for (i = j = 0; i < hayn;) { while (j != SIZE_MAX && sub[j] != hay[i]) j = next[j]; i++; if (++j == subn) { hay = &hay[i - j]; return REMOVE_CONST(hay, unsigned char *); } } return NULL; } #else #include "test.h" int main(void) { assert(!strcmpnul(libsimple_memmem("test", 4, "test", 4), "test")); assert(!strcmpnul(libsimple_memmem("", 0, "", 0), "")); assert(!strcmpnul(libsimple_memmem("test", 4, "", 0), "test")); assert(!libsimple_memmem("", 0, "test", 4)); assert(!libsimple_memmem("t", 1, "test", 4)); assert(!strcmpnul(libsimple_memmem("test", 4, "t", 1), "test")); assert(!strcmpnul(libsimple_memmem("test", 4, "e", 1), "est")); assert(!strcmpnul(libsimple_memmem("test", 4, "s", 1), "st")); assert(!libsimple_memmem("test", 4, "x", 1)); assert(!strcmpnul(libsimple_memmem("test", 4, "te", 2), "test")); assert(!strcmpnul(libsimple_memmem("test", 4, "es", 2), "est")); assert(!strcmpnul(libsimple_memmem("test", 4, "st", 2), "st")); assert(!strcmpnul(libsimple_memmem("test", 5, "t", 2), "t")); assert(!libsimple_memmem("test", 4, "xx", 2)); assert(!strcmpnul(libsimple_memmem("abc", 3, "c", 1), "c")); assert(!strcmpnul(libsimple_memmem("abc", 3, "bc", 2), "bc")); assert(!strcmpnul(libsimple_memmem("abc", 3, "abc", 3), "abc")); assert(!libsimple_memmem("abc", 3, "abc", 4)); assert(!strcmpnul(libsimple_memmem("abcabc", 6, "bc", 2), "bcabc")); assert(!strcmpnul(libsimple_memmem("ABCABC", 6, "BC", 2), "BCABC")); assert(!libsimple_memmem("ABCDEF", 6, "bc", 2)); assert(!libsimple_memmem("abcdef", 6, "BC", 2)); return 0; } #endif