/* See LICENSE file for copyright and license details. */ #include "common.h" LIBAUTOMATA_MP_AUTOMATON * libautomata_compile_mp_automaton(const void *pattern, size_t length, size_t elemsize) { size_t i = 0, j = SIZE_MAX; size_t size = sizeof_mp_automaton(length, elemsize); LIBAUTOMATA_MP_AUTOMATON *ret = malloc(size); if (!ret) return NULL; ret->position = 0; ret->length = length; ret->elemsize = elemsize; memcpy((void *)&ret->next[length + 1U], pattern, length * elemsize); #define INTRINSIC(TYPE)\ (((const TYPE *)pattern)[i] == ((const TYPE *)pattern)[j]) #define MEMCMP(WIDTH)\ (!memcmp(&((const char *)pattern)[i * (WIDTH)], &((const char *)pattern)[j * (WIDTH)], (WIDTH))) #define IMPLEMENT(EQ, EQ_PARAM, CASE)\ while (i < length) {\ if (j != SIZE_MAX && !(EQ(EQ_PARAM)))\ j = ret->next[j];\ i++;\ j++;\ CASE:\ ret->next[i] = j;\ }\ return ret switch (elemsize) { IMPLEMENT(INTRINSIC, uint8_t, case sizeof(uint8_t)); IMPLEMENT(INTRINSIC, uint16_t, case sizeof(uint16_t)); IMPLEMENT(INTRINSIC, uint32_t, case sizeof(uint32_t)); IMPLEMENT(INTRINSIC, uint64_t, case sizeof(uint64_t)); IMPLEMENT(MEMCMP, elemsize, default); } }