-
Notifications
You must be signed in to change notification settings - Fork 53
/
grok.c
131 lines (114 loc) · 4.15 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
130
131
#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;
int g_cap_definition = 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");
g_cap_definition = pcre_get_stringnumber(g_pattern_re, "definition");
}
}
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 */