forked from jordansissel/grok
-
Notifications
You must be signed in to change notification settings - Fork 0
/
grok.c
129 lines (112 loc) · 4.05 KB
/
grok.c
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "grok.h"
#include <dlfcn.h>
static int grok_pcre_callout(pcre_callout_block *pcb);
int g_grok_global_initialized = 0;
pcre *g_pattern_re = NULL;
int g_pattern_num_captures = 0;
int g_cap_name = 0;
int g_cap_pattern = 0;
int g_cap_subname = 0;
int g_cap_predicate = 0;
grok_t *grok_new() {
grok_t *grok;
grok = malloc(sizeof(grok_t));
grok_init(grok);
return grok;
}
void grok_init(grok_t *grok) {
//int ret;
/* set global pcre_callout for libpcre */
pcre_callout = grok_pcre_callout;
grok->re = NULL;
grok->pattern = NULL;
grok->full_pattern = NULL;
grok->pcre_capture_vector = NULL;
grok->pcre_num_captures = 0;
grok->max_capture_num = 0;
grok->pcre_errptr = NULL;
grok->pcre_erroffset = 0;
grok->logmask = 0;
grok->logdepth = 0;
#ifndef GROK_TEST_NO_PATTERNS
grok->patterns = tctreenew();
#endif /* GROK_TEST_NO_PATTERNS */
#ifndef GROK_TEST_NO_CAPTURE
grok->captures_by_id = tctreenew();
grok->captures_by_name = tctreenew();
grok->captures_by_subname = tctreenew();
grok->captures_by_capture_number = tctreenew();
#endif /* GROK_TEST_NO_CAPTURE */
if (g_grok_global_initialized == 0) {
/* do first initalization */
g_grok_global_initialized = 1;
/* VALGRIND NOTE: Valgrind complains here, but this is a global variable.
* Ignore valgrind here. */
g_pattern_re = pcre_compile(PATTERN_REGEX, 0,
&grok->pcre_errptr,
&grok->pcre_erroffset,
NULL);
if (g_pattern_re == NULL) {
fprintf(stderr, "Internal compiler error: %s\n", grok->pcre_errptr);
fprintf(stderr, "Regexp: %s\n", PATTERN_REGEX);
fprintf(stderr, "Position: %d\n", grok->pcre_erroffset);
}
pcre_fullinfo(g_pattern_re, NULL, PCRE_INFO_CAPTURECOUNT,
&g_pattern_num_captures);
g_pattern_num_captures++; /* include the 0th group */
g_cap_name = pcre_get_stringnumber(g_pattern_re, "name");
g_cap_pattern = pcre_get_stringnumber(g_pattern_re, "pattern");
g_cap_subname = pcre_get_stringnumber(g_pattern_re, "subname");
g_cap_predicate = pcre_get_stringnumber(g_pattern_re, "predicate");
}
}
void grok_clone(grok_t *dst, const grok_t *src) {
grok_init(dst);
dst->patterns = src->patterns;
dst->logmask = src->logmask;
dst->logdepth = src->logdepth + 1;
}
static int grok_pcre_callout(pcre_callout_block *pcb) {
grok_t *grok = pcb->callout_data;
const grok_capture *gct;
gct = (grok_capture *)grok_capture_get_by_capture_number(grok,
pcb->capture_last);
/* TODO(sissel): handle case where gct is not found (== NULL) */
if (gct->predicate_func_name != NULL) {
int (*predicate)(grok_t *, const grok_capture *, const char *, int, int);
int start, end;
void *handle;
char *lib = gct->predicate_lib;
start = pcb->offset_vector[ pcb->capture_last * 2 ];
end = pcb->offset_vector[ pcb->capture_last * 2 + 1];
if (lib != NULL && lib[0] == '\0') {
lib = NULL;
}
/* Hack so if we are dlopen()'d we can still find ourselves
* This is necessary for cases like Ruby FFI which only dlopen's us
* and does not explicitly link/load us? */
#ifdef PLATFORM_Darwin
lib = "libgrok.dylib";
#else
lib = "libgrok.so";
#endif
handle = dlopen(lib, RTLD_LAZY);
predicate = dlsym(handle, gct->predicate_func_name);
if (predicate != NULL) {
grok_log(grok, LOG_EXEC, "start pcre_callout func %s/%.*s",
(lib == NULL ? "grok" : lib), gct->predicate_func_name_len,
gct->predicate_func_name);
int ret;
ret = predicate(grok, gct, pcb->subject, start, end);
grok_log(grok, LOG_EXEC, "end pcre_callout func %s/%.*s returned: %d",
(lib == NULL ? "grok" : lib), gct->predicate_func_name_len,
gct->predicate_func_name, ret);
return ret;
} else {
grok_log(grok, LOG_EXEC, "No such function '%s' in library '%s'",
gct->predicate_func_name, lib);
return 0;
}
}
return 0;
} /* int grok_pcre_callout */