1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
LIBAUTOMATA_KMP_AUTOMATON *
libautomata_compile_kmp_automaton(const void *pattern, size_t length, size_t elemsize)
{
size_t i = 0, j = SIZE_MAX;
size_t size = sizeof_kmp_automaton(length, elemsize);
LIBAUTOMATA_KMP_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++;\
if (EQ(EQ_PARAM))\
ret->next[i] = ret->next[j];\
else 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);
}
}
|