jls-grok 0.1.2786
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/INSTALL +12 -0
- data/ext/Grok.so +0 -0
- data/ext/Makefile +157 -0
- data/ext/extconf.rb +7 -0
- data/ext/mkmf.log +54 -0
- data/ext/rgrok.h +9 -0
- data/ext/ruby_grok.c +190 -0
- data/ext/ruby_grok.o +0 -0
- data/ext/ruby_grokmatch.c +220 -0
- data/ext/ruby_grokmatch.h +14 -0
- data/ext/ruby_grokmatch.o +0 -0
- data/lib/grok.rb +1 -0
- data/sample.rb +43 -0
- data/test/GDB_COMMAND +29 -0
- data/test/Makefile +7 -0
- data/test/alltests.rb +6 -0
- data/test/general/basic_test.rb +58 -0
- data/test/general/captures_test.rb +88 -0
- data/test/patterns/ip.input +10000 -0
- data/test/patterns/ip.rb +32 -0
- data/test/patterns/month.rb +25 -0
- data/test/patterns/number.rb +70 -0
- data/test/patterns/path.rb +32 -0
- data/test/patterns/quotedstring.rb +54 -0
- data/test/patterns/uri.rb +44 -0
- data/test/speedtest.rb +56 -0
- metadata +90 -0
data/INSTALL
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
- You'll need grok installed.
|
2
|
+
From 'grok', do:
|
3
|
+
% make install
|
4
|
+
# This will install grok, libgrok, and grok's headers
|
5
|
+
|
6
|
+
- You'll need the 'Grok' ruby module installed.
|
7
|
+
From 'grok/ruby' do:
|
8
|
+
% ruby extconf.rb
|
9
|
+
% make install
|
10
|
+
|
11
|
+
# Test with:
|
12
|
+
% ruby -e 'require "Grok"; puts "Grok OK"'
|
data/ext/Grok.so
ADDED
Binary file
|
data/ext/Makefile
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
#### Start of system configuration section. ####
|
5
|
+
|
6
|
+
srcdir = .
|
7
|
+
topdir = /usr/lib/ruby/1.8/x86_64-linux
|
8
|
+
hdrdir = $(topdir)
|
9
|
+
VPATH = $(srcdir):$(topdir):$(hdrdir)
|
10
|
+
exec_prefix = $(prefix)
|
11
|
+
prefix = $(DESTDIR)/usr
|
12
|
+
sharedstatedir = $(prefix)/com
|
13
|
+
mandir = $(prefix)/share/man
|
14
|
+
psdir = $(docdir)
|
15
|
+
oldincludedir = $(DESTDIR)/usr/include
|
16
|
+
localedir = $(datarootdir)/locale
|
17
|
+
bindir = $(exec_prefix)/bin
|
18
|
+
libexecdir = $(prefix)/lib/ruby1.8
|
19
|
+
sitedir = $(DESTDIR)/usr/local/lib/site_ruby
|
20
|
+
htmldir = $(docdir)
|
21
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
22
|
+
includedir = $(prefix)/include
|
23
|
+
infodir = $(prefix)/share/info
|
24
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
25
|
+
sysconfdir = $(DESTDIR)/etc
|
26
|
+
libdir = $(exec_prefix)/lib
|
27
|
+
sbindir = $(exec_prefix)/sbin
|
28
|
+
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
29
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
30
|
+
dvidir = $(docdir)
|
31
|
+
vendordir = $(libdir)/ruby/vendor_ruby
|
32
|
+
datarootdir = $(prefix)/share
|
33
|
+
pdfdir = $(docdir)
|
34
|
+
archdir = $(rubylibdir)/$(arch)
|
35
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
36
|
+
datadir = $(datarootdir)
|
37
|
+
localstatedir = $(DESTDIR)/var
|
38
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
39
|
+
|
40
|
+
CC = gcc
|
41
|
+
LIBRUBY = $(LIBRUBY_SO)
|
42
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
43
|
+
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
44
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
45
|
+
|
46
|
+
RUBY_EXTCONF_H =
|
47
|
+
CFLAGS = -fPIC -fno-strict-aliasing -g -g -O2 -fPIC $(cflags)
|
48
|
+
INCFLAGS = -I. -I. -I/usr/lib/ruby/1.8/x86_64-linux -I.
|
49
|
+
DEFS =
|
50
|
+
CPPFLAGS =
|
51
|
+
CXXFLAGS = $(CFLAGS)
|
52
|
+
ldflags = -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic
|
53
|
+
dldflags =
|
54
|
+
archflag =
|
55
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
|
56
|
+
LDSHARED = $(CC) -shared
|
57
|
+
AR = ar
|
58
|
+
EXEEXT =
|
59
|
+
|
60
|
+
RUBY_INSTALL_NAME = ruby1.8
|
61
|
+
RUBY_SO_NAME = ruby1.8
|
62
|
+
arch = x86_64-linux
|
63
|
+
sitearch = x86_64-linux
|
64
|
+
ruby_version = 1.8
|
65
|
+
ruby = /usr/bin/ruby1.8
|
66
|
+
RUBY = $(ruby)
|
67
|
+
RM = rm -f
|
68
|
+
MAKEDIRS = mkdir -p
|
69
|
+
INSTALL = /usr/bin/install -c
|
70
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
71
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
72
|
+
COPY = cp
|
73
|
+
|
74
|
+
#### End of system configuration section. ####
|
75
|
+
|
76
|
+
preload =
|
77
|
+
|
78
|
+
libpath = . $(libdir)
|
79
|
+
LIBPATH = -L. -L$(libdir)
|
80
|
+
DEFFILE =
|
81
|
+
|
82
|
+
CLEANFILES = mkmf.log
|
83
|
+
DISTCLEANFILES =
|
84
|
+
|
85
|
+
extout =
|
86
|
+
extout_prefix =
|
87
|
+
target_prefix =
|
88
|
+
LOCAL_LIBS =
|
89
|
+
LIBS = $(LIBRUBYARG_SHARED) -lgrok -lpthread -lrt -ldl -lcrypt -lm -lc
|
90
|
+
SRCS = ruby_grok.c ruby_grokmatch.c
|
91
|
+
OBJS = ruby_grok.o ruby_grokmatch.o
|
92
|
+
TARGET = Grok
|
93
|
+
DLLIB = $(TARGET).so
|
94
|
+
EXTSTATIC =
|
95
|
+
STATIC_LIB =
|
96
|
+
|
97
|
+
BINDIR = $(bindir)
|
98
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
99
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
100
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
101
|
+
|
102
|
+
TARGET_SO = $(DLLIB)
|
103
|
+
CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
|
104
|
+
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
|
105
|
+
|
106
|
+
all: $(DLLIB)
|
107
|
+
static: $(STATIC_LIB)
|
108
|
+
|
109
|
+
clean:
|
110
|
+
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
111
|
+
|
112
|
+
distclean: clean
|
113
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
114
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
115
|
+
|
116
|
+
realclean: distclean
|
117
|
+
install: install-so install-rb
|
118
|
+
|
119
|
+
install-so: $(RUBYARCHDIR)
|
120
|
+
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
121
|
+
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
122
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
123
|
+
install-rb: pre-install-rb install-rb-default
|
124
|
+
install-rb-default: pre-install-rb-default
|
125
|
+
pre-install-rb: Makefile
|
126
|
+
pre-install-rb-default: Makefile
|
127
|
+
$(RUBYARCHDIR):
|
128
|
+
$(MAKEDIRS) $@
|
129
|
+
|
130
|
+
site-install: site-install-so site-install-rb
|
131
|
+
site-install-so: install-so
|
132
|
+
site-install-rb: install-rb
|
133
|
+
|
134
|
+
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
135
|
+
|
136
|
+
.cc.o:
|
137
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
138
|
+
|
139
|
+
.cxx.o:
|
140
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
141
|
+
|
142
|
+
.cpp.o:
|
143
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
144
|
+
|
145
|
+
.C.o:
|
146
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
147
|
+
|
148
|
+
.c.o:
|
149
|
+
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
|
150
|
+
|
151
|
+
$(DLLIB): $(OBJS) Makefile
|
152
|
+
@-$(RM) $@
|
153
|
+
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
$(OBJS): ruby.h defines.h
|
data/ext/extconf.rb
ADDED
data/ext/mkmf.log
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
find_header: checking for tcutil.h in /usr/local/include... -------------------- yes
|
2
|
+
|
3
|
+
"gcc -E -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fno-strict-aliasing -g -g -O2 -fPIC conftest.c -o conftest.i"
|
4
|
+
checked program was:
|
5
|
+
/* begin */
|
6
|
+
1: #include <tcutil.h>
|
7
|
+
/* end */
|
8
|
+
|
9
|
+
--------------------
|
10
|
+
|
11
|
+
find_header: checking for pcre.h in /usr/local/include... -------------------- yes
|
12
|
+
|
13
|
+
"gcc -E -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fno-strict-aliasing -g -g -O2 -fPIC conftest.c -o conftest.i"
|
14
|
+
checked program was:
|
15
|
+
/* begin */
|
16
|
+
1: #include <pcre.h>
|
17
|
+
/* end */
|
18
|
+
|
19
|
+
--------------------
|
20
|
+
|
21
|
+
find_header: checking for grok.h in ../... -------------------- yes
|
22
|
+
|
23
|
+
"gcc -E -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fno-strict-aliasing -g -g -O2 -fPIC conftest.c -o conftest.i"
|
24
|
+
checked program was:
|
25
|
+
/* begin */
|
26
|
+
1: #include <grok.h>
|
27
|
+
/* end */
|
28
|
+
|
29
|
+
--------------------
|
30
|
+
|
31
|
+
find_library: checking for grok_init() in -lgrok... -------------------- yes
|
32
|
+
|
33
|
+
"gcc -o conftest -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fno-strict-aliasing -g -g -O2 -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic -lruby1.8-static -lgrok -lpthread -lrt -ldl -lcrypt -lm -lc"
|
34
|
+
conftest.c: In function 't':
|
35
|
+
conftest.c:3: error: 'grok_init' undeclared (first use in this function)
|
36
|
+
conftest.c:3: error: (Each undeclared identifier is reported only once
|
37
|
+
conftest.c:3: error: for each function it appears in.)
|
38
|
+
checked program was:
|
39
|
+
/* begin */
|
40
|
+
1: /*top*/
|
41
|
+
2: int main() { return 0; }
|
42
|
+
3: int t() { void ((*volatile p)()); p = (void ((*)()))grok_init; return 0; }
|
43
|
+
/* end */
|
44
|
+
|
45
|
+
"gcc -o conftest -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fno-strict-aliasing -g -g -O2 -fPIC conftest.c -L. -L/usr/lib -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic -lruby1.8-static -lgrok -lpthread -lrt -ldl -lcrypt -lm -lc"
|
46
|
+
checked program was:
|
47
|
+
/* begin */
|
48
|
+
1: /*top*/
|
49
|
+
2: int main() { return 0; }
|
50
|
+
3: int t() { grok_init(); return 0; }
|
51
|
+
/* end */
|
52
|
+
|
53
|
+
--------------------
|
54
|
+
|
data/ext/rgrok.h
ADDED
data/ext/ruby_grok.c
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <grok.h>
|
3
|
+
#include "rgrok.h"
|
4
|
+
#include "ruby_grokmatch.h"
|
5
|
+
|
6
|
+
VALUE cGrok; /* Grok class object */
|
7
|
+
|
8
|
+
extern VALUE cGrokMatch;
|
9
|
+
extern void Init_GrokMatch();
|
10
|
+
|
11
|
+
static VALUE rGrok_initialize(VALUE self) {
|
12
|
+
/* empty */
|
13
|
+
return Qnil;
|
14
|
+
}
|
15
|
+
|
16
|
+
static void rGrok_free(void *p) {
|
17
|
+
grok_t *grok = (grok_t *)p;
|
18
|
+
|
19
|
+
/* we strdup our pattern from ruby and rb_str2cstr */
|
20
|
+
/* typecast to ignore warnings about freeing a const...
|
21
|
+
* TODO(sissel): Fix the constness */
|
22
|
+
free((char *)grok->pattern);
|
23
|
+
|
24
|
+
grok_free(grok);
|
25
|
+
free(grok);
|
26
|
+
}
|
27
|
+
|
28
|
+
VALUE rGrok_new(VALUE klass) {
|
29
|
+
VALUE rgrok;
|
30
|
+
grok_t *grok = ALLOC(grok_t);
|
31
|
+
grok_init(grok);
|
32
|
+
//grok->logmask = ~0;
|
33
|
+
rgrok = Data_Wrap_Struct(klass, 0, rGrok_free, grok);
|
34
|
+
rb_obj_call_init(rgrok, 0, 0);
|
35
|
+
return rgrok;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE rGrok_compile(VALUE self, VALUE pattern) {
|
39
|
+
grok_t *grok;
|
40
|
+
char *c_pattern = NULL;
|
41
|
+
char *str = NULL;
|
42
|
+
long len = 0;
|
43
|
+
int ret = 0;
|
44
|
+
Data_Get_Struct(self, grok_t, grok);
|
45
|
+
|
46
|
+
/* Need strdup here in case 'pattern' object is deleted later in
|
47
|
+
* the ruby code */
|
48
|
+
str = rb_str2cstr(pattern, &len);
|
49
|
+
c_pattern = malloc(len);
|
50
|
+
memcpy(c_pattern, str, len);
|
51
|
+
|
52
|
+
if (grok->pattern != NULL) {
|
53
|
+
/* if we've already called compile, let's free up the string we
|
54
|
+
* allocated last time */
|
55
|
+
|
56
|
+
/* typecast to break constness. TODO(sissel): fix const */
|
57
|
+
free((char *)grok->pattern);
|
58
|
+
}
|
59
|
+
|
60
|
+
ret = grok_compilen(grok, c_pattern, (int)len);
|
61
|
+
if (ret) {
|
62
|
+
rb_raise(rb_eArgError, "Compile failed: %s", grok->errstr);
|
63
|
+
}
|
64
|
+
|
65
|
+
return Qnil;
|
66
|
+
}
|
67
|
+
|
68
|
+
VALUE rGrok_match(VALUE self, VALUE input) {
|
69
|
+
grok_t *grok = NULL;
|
70
|
+
grok_match_t gm;
|
71
|
+
char *c_input = NULL;
|
72
|
+
long len = 0;
|
73
|
+
int ret = 0;
|
74
|
+
|
75
|
+
Data_Get_Struct(self, grok_t, grok);
|
76
|
+
c_input = rb_str2cstr(input, &len);
|
77
|
+
ret = grok_execn(grok, c_input, (int)len, &gm);
|
78
|
+
|
79
|
+
VALUE rgm = Qnil;
|
80
|
+
|
81
|
+
//fprintf(stderr, "%d\n", ret);
|
82
|
+
switch (ret) {
|
83
|
+
case GROK_ERROR_NOMATCH:
|
84
|
+
rgm = Qfalse;
|
85
|
+
break;
|
86
|
+
case GROK_OK:
|
87
|
+
rgm = rGrokMatch_new_from_grok_match(&gm);
|
88
|
+
break;
|
89
|
+
default:
|
90
|
+
rb_raise(rb_eArgError, "Error from grok_execn: %d", ret);
|
91
|
+
rgm = Qfalse;
|
92
|
+
}
|
93
|
+
|
94
|
+
return rgm;
|
95
|
+
}
|
96
|
+
|
97
|
+
VALUE rGrok_add_pattern(VALUE self, VALUE name, VALUE pattern) {
|
98
|
+
grok_t *grok = NULL;
|
99
|
+
char *c_name= NULL, *c_pattern = NULL;
|
100
|
+
long namelen = 0, patternlen = 0;
|
101
|
+
|
102
|
+
/* Don't need strdup here, since grok_pattern_add will store a copy
|
103
|
+
* if the data */
|
104
|
+
c_name = rb_str2cstr(name, &namelen);
|
105
|
+
c_pattern = rb_str2cstr(pattern, &patternlen);
|
106
|
+
Data_Get_Struct(self, grok_t, grok);
|
107
|
+
|
108
|
+
grok_pattern_add(grok, c_name, namelen, c_pattern, patternlen);
|
109
|
+
return Qnil;
|
110
|
+
}
|
111
|
+
|
112
|
+
VALUE rGrok_add_patterns_from_file(VALUE self, VALUE path) {
|
113
|
+
grok_t *grok = NULL;
|
114
|
+
int ret = 0;
|
115
|
+
char *c_path = NULL;
|
116
|
+
long pathlen = 0;
|
117
|
+
|
118
|
+
/* don't need strdup here, since we don't store 'path' long-term */
|
119
|
+
c_path = rb_str2cstr(path, &pathlen);
|
120
|
+
Data_Get_Struct(self, grok_t, grok);
|
121
|
+
|
122
|
+
ret = grok_patterns_import_from_file(grok, c_path);
|
123
|
+
|
124
|
+
if (ret != GROK_OK) {
|
125
|
+
rb_raise(rb_eArgError, "Failed to add patterns from file %s", c_path);
|
126
|
+
}
|
127
|
+
|
128
|
+
return Qnil;
|
129
|
+
}
|
130
|
+
|
131
|
+
VALUE rGrok_expanded_pattern(VALUE self) {
|
132
|
+
grok_t *grok = NULL;
|
133
|
+
VALUE expanded_pattern;
|
134
|
+
|
135
|
+
Data_Get_Struct(self, grok_t, grok);
|
136
|
+
expanded_pattern = rb_str_new(grok->full_pattern, grok->full_pattern_len);
|
137
|
+
return expanded_pattern;
|
138
|
+
}
|
139
|
+
|
140
|
+
VALUE rGrok_pattern(VALUE self) {
|
141
|
+
grok_t *grok = NULL;
|
142
|
+
VALUE pattern;
|
143
|
+
|
144
|
+
Data_Get_Struct(self, grok_t, grok);
|
145
|
+
pattern = rb_str_new(grok->pattern, grok->pattern_len);
|
146
|
+
return pattern;
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE rGrok_patterns(VALUE self) {
|
150
|
+
VALUE patternmap = rb_hash_new();
|
151
|
+
TCLIST *names = NULL;
|
152
|
+
grok_t *grok = NULL;
|
153
|
+
int i = 0, len = 0;
|
154
|
+
|
155
|
+
Data_Get_Struct(self, grok_t, grok);
|
156
|
+
names = grok_pattern_name_list(grok);
|
157
|
+
|
158
|
+
len = tclistnum(names);
|
159
|
+
for (i = 0; i < len; i++) {
|
160
|
+
int namelen = 0;
|
161
|
+
const char *name = tclistval(names, i, &namelen);
|
162
|
+
size_t regexplen = 0;
|
163
|
+
const char *regexp = NULL;
|
164
|
+
grok_pattern_find(grok, name, namelen, ®exp, ®explen);
|
165
|
+
|
166
|
+
VALUE key;
|
167
|
+
VALUE value;
|
168
|
+
key = rb_tainted_str_new(name, namelen);
|
169
|
+
value = rb_tainted_str_new(regexp, regexplen);
|
170
|
+
rb_hash_aset(patternmap, key, value);
|
171
|
+
}
|
172
|
+
tclistdel(names);
|
173
|
+
return patternmap;
|
174
|
+
}
|
175
|
+
|
176
|
+
void Init_Grok() {
|
177
|
+
cGrok = rb_define_class("Grok", rb_cObject);
|
178
|
+
rb_define_singleton_method(cGrok, "new", rGrok_new, 0);
|
179
|
+
rb_define_method(cGrok, "initialize", rGrok_initialize, 0);
|
180
|
+
rb_define_method(cGrok, "compile", rGrok_compile, 1);
|
181
|
+
rb_define_method(cGrok, "match", rGrok_match, 1);
|
182
|
+
rb_define_method(cGrok, "expanded_pattern", rGrok_expanded_pattern, 0);
|
183
|
+
rb_define_method(cGrok, "pattern", rGrok_pattern, 0);
|
184
|
+
rb_define_method(cGrok, "add_pattern", rGrok_add_pattern, 2);
|
185
|
+
rb_define_method(cGrok, "add_patterns_from_file",
|
186
|
+
rGrok_add_patterns_from_file, 1);
|
187
|
+
rb_define_method(cGrok, "patterns", rGrok_patterns, 0);
|
188
|
+
|
189
|
+
Init_GrokMatch();
|
190
|
+
}
|
data/ext/ruby_grok.o
ADDED
Binary file
|
@@ -0,0 +1,220 @@
|
|
1
|
+
#include "rgrok.h"
|
2
|
+
#include <grok.h>
|
3
|
+
|
4
|
+
VALUE cGrokMatch;
|
5
|
+
extern VALUE cGrok;
|
6
|
+
|
7
|
+
static ID id_atend;
|
8
|
+
static ID id_atstart;
|
9
|
+
static ID id_atcaptures;
|
10
|
+
static ID id_atsubject;
|
11
|
+
|
12
|
+
static ID id_length;
|
13
|
+
static ID id_has_key_p;
|
14
|
+
|
15
|
+
static void rGrokMatch_free(void *p);
|
16
|
+
|
17
|
+
VALUE rGrokMatch_new(VALUE klass) {
|
18
|
+
NEWOBJ(rgm, grok_match_t);
|
19
|
+
OBJSETUP(rgm, klass, T_OBJECT);
|
20
|
+
|
21
|
+
return (VALUE)rgm;
|
22
|
+
}
|
23
|
+
|
24
|
+
VALUE rGrokMatch_new_from_grok_match(grok_match_t *gm) {
|
25
|
+
VALUE rgrokmatch;
|
26
|
+
grok_match_t *my_gm = NULL;
|
27
|
+
rgrokmatch = Data_Make_Struct(cGrokMatch, grok_match_t, 0,
|
28
|
+
rGrokMatch_free, my_gm);
|
29
|
+
memcpy(my_gm, gm, sizeof(grok_match_t));
|
30
|
+
|
31
|
+
/* We must strdup here, otherwise ruby GC may come and re-arrange
|
32
|
+
* rb_str2cstr() can give a pointer to an object that is later deleted. When
|
33
|
+
* deleted, we won't know about it, and we'll get a garbage string from that
|
34
|
+
* pointer.
|
35
|
+
*
|
36
|
+
* TODO(sissel): make a GrokMatch 'ruby' friendly struct
|
37
|
+
* that uses VALUE types for subject.
|
38
|
+
*/
|
39
|
+
my_gm->subject = strdup(gm->subject);
|
40
|
+
rb_obj_call_init(rgrokmatch, 0, 0);
|
41
|
+
return rgrokmatch;
|
42
|
+
}
|
43
|
+
|
44
|
+
VALUE rGrokMatch_initialize(VALUE self) {
|
45
|
+
grok_match_t *gm;
|
46
|
+
VALUE captures;
|
47
|
+
|
48
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
49
|
+
|
50
|
+
/* Set the @captures variable to a hash of array of strings */
|
51
|
+
captures = rb_hash_new();
|
52
|
+
//captures = rb_eval_string("Hash.new { |h,k| h[k] = Array.new }");
|
53
|
+
rb_iv_set(self, "@captures", captures);
|
54
|
+
|
55
|
+
return Qtrue;
|
56
|
+
}
|
57
|
+
|
58
|
+
VALUE rGrokMatch_each_capture(VALUE self) {
|
59
|
+
char *name;
|
60
|
+
const char *data;
|
61
|
+
int namelen, datalen;
|
62
|
+
grok_match_t *gm;
|
63
|
+
VALUE captures;
|
64
|
+
|
65
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
66
|
+
captures = rb_iv_get(self, "@captures");
|
67
|
+
grok_match_walk_init(gm);
|
68
|
+
while (grok_match_walk_next(gm, &name, &namelen, &data, &datalen) == 0) {
|
69
|
+
VALUE key, value;
|
70
|
+
|
71
|
+
#ifdef _TRIM_KEY_EXCESS_IN_C_
|
72
|
+
/* This section will skip captures of %{FOO} and rename captures of
|
73
|
+
* %{FOO:bar} to just 'bar' */
|
74
|
+
size_t koff = 0;
|
75
|
+
/* there is no 'strcspn' that takes a length, so do it ourselves */
|
76
|
+
while (koff < namelen && name[koff] != ':' && name[koff] != '\0') {
|
77
|
+
koff++;
|
78
|
+
}
|
79
|
+
|
80
|
+
/* Skip captures that aren't named specially */
|
81
|
+
if (koff == namelen) {
|
82
|
+
//printf("Skipping %.*s\n", namelen, name);
|
83
|
+
continue;
|
84
|
+
}
|
85
|
+
|
86
|
+
koff++;
|
87
|
+
|
88
|
+
key = rb_tainted_str_new(name + koff, namelen - koff);
|
89
|
+
#else
|
90
|
+
key = rb_tainted_str_new(name, namelen);
|
91
|
+
#endif
|
92
|
+
value = rb_tainted_str_new(data, datalen);
|
93
|
+
|
94
|
+
// Yield [key, value]
|
95
|
+
rb_yield(rb_ary_new3(2, key, value));
|
96
|
+
//rb_ary_push(ary, value);
|
97
|
+
}
|
98
|
+
|
99
|
+
grok_match_walk_end(gm);
|
100
|
+
return Qtrue;
|
101
|
+
}
|
102
|
+
|
103
|
+
VALUE rGrokMatch_captures(VALUE self) {
|
104
|
+
char *name;
|
105
|
+
const char *data;
|
106
|
+
int namelen, datalen;
|
107
|
+
grok_match_t *gm;
|
108
|
+
VALUE captures;
|
109
|
+
|
110
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
111
|
+
captures = rb_iv_get(self, "@captures");
|
112
|
+
|
113
|
+
if (captures == Qnil) {
|
114
|
+
captures = rb_hash_new();
|
115
|
+
}
|
116
|
+
|
117
|
+
if (FIX2INT(rb_funcall(captures, id_length, 0)) > 0) {
|
118
|
+
//if (FIX2NUM(rb_hash_size(captures)) > 0) {
|
119
|
+
return captures;
|
120
|
+
}
|
121
|
+
|
122
|
+
grok_match_walk_init(gm);
|
123
|
+
while (grok_match_walk_next(gm, &name, &namelen, &data, &datalen) == 0) {
|
124
|
+
VALUE key = Qnil;
|
125
|
+
VALUE value = Qnil;
|
126
|
+
|
127
|
+
#ifdef _TRIM_KEY_EXCESS_IN_C_
|
128
|
+
/* This section will skip captures of %{FOO} and rename captures of
|
129
|
+
* %{FOO:bar} to just 'bar' */
|
130
|
+
size_t koff = 0;
|
131
|
+
/* there is no 'strcspn' that takes a length, so do it ourselves */
|
132
|
+
while (koff < namelen && name[koff] != ':' && name[koff] != '\0') {
|
133
|
+
koff++;
|
134
|
+
}
|
135
|
+
|
136
|
+
/* Skip captures that aren't named specially */
|
137
|
+
if (koff == namelen) {
|
138
|
+
//printf("Skipping %.*s\n", namelen, name);
|
139
|
+
continue;
|
140
|
+
}
|
141
|
+
|
142
|
+
koff++;
|
143
|
+
|
144
|
+
key = rb_tainted_str_new(name + koff, namelen - koff);
|
145
|
+
#else
|
146
|
+
key = rb_tainted_str_new(name, namelen);
|
147
|
+
#endif
|
148
|
+
value = rb_tainted_str_new(data, datalen);
|
149
|
+
|
150
|
+
VALUE array;
|
151
|
+
//if (rb_hash_has_key(captures, key) == Qfalse) {
|
152
|
+
if (rb_funcall(captures, id_has_key_p, 1, key) == Qfalse) {
|
153
|
+
array = rb_hash_aset(captures, key, rb_ary_new());
|
154
|
+
} else {
|
155
|
+
array = rb_hash_aref(captures, key);
|
156
|
+
}
|
157
|
+
rb_ary_push(array, value);
|
158
|
+
}
|
159
|
+
|
160
|
+
grok_match_walk_end(gm);
|
161
|
+
return captures;
|
162
|
+
}
|
163
|
+
|
164
|
+
VALUE rGrokMatch_start(VALUE self) {
|
165
|
+
grok_match_t *gm;
|
166
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
167
|
+
return INT2FIX(gm->start);
|
168
|
+
}
|
169
|
+
|
170
|
+
VALUE rGrokMatch_end(VALUE self) {
|
171
|
+
grok_match_t *gm;
|
172
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
173
|
+
VALUE ret = Qnil;
|
174
|
+
ret = rb_iv_get(self, "@end");
|
175
|
+
if (ret == Qnil) {
|
176
|
+
ret = rb_iv_set(self, "@end", INT2FIX(gm->end));
|
177
|
+
}
|
178
|
+
return INT2FIX(gm->end);
|
179
|
+
}
|
180
|
+
|
181
|
+
VALUE rGrokMatch_subject(VALUE self) {
|
182
|
+
grok_match_t *gm;
|
183
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
184
|
+
return rb_tainted_str_new2(gm->subject);
|
185
|
+
}
|
186
|
+
|
187
|
+
VALUE rGrokMatch_debug(VALUE self) {
|
188
|
+
grok_match_t *gm;
|
189
|
+
Data_Get_Struct(self, grok_match_t, gm);
|
190
|
+
printf("match subject: %s\n", gm->subject);
|
191
|
+
printf("match start: %d\n", gm->start);
|
192
|
+
printf("match end: %d\n", gm->end);
|
193
|
+
printf("grok pattern: %s\n", gm->grok->pattern);
|
194
|
+
return Qnil;
|
195
|
+
}
|
196
|
+
|
197
|
+
void rGrokMatch_free(void *p) {
|
198
|
+
grok_match_t *gm = (grok_match_t *)p;
|
199
|
+
free((char *)gm->subject);
|
200
|
+
}
|
201
|
+
|
202
|
+
void Init_GrokMatch() {
|
203
|
+
cGrokMatch = rb_define_class("GrokMatch", rb_cObject);
|
204
|
+
rb_define_singleton_method(cGrokMatch, "new", rGrokMatch_new, 0);
|
205
|
+
rb_define_method(cGrokMatch, "initialize", rGrokMatch_initialize, 0);
|
206
|
+
rb_define_method(cGrokMatch, "captures", rGrokMatch_captures, 0);
|
207
|
+
rb_define_method(cGrokMatch, "start", rGrokMatch_start, 0);
|
208
|
+
rb_define_method(cGrokMatch, "end", rGrokMatch_end, 0);
|
209
|
+
rb_define_method(cGrokMatch, "subject", rGrokMatch_subject, 0);
|
210
|
+
rb_define_method(cGrokMatch, "each_capture", rGrokMatch_each_capture, 0);
|
211
|
+
|
212
|
+
//rb_define_method(cGrokMatch, "debug", rGrokMatch_debug, 0);
|
213
|
+
|
214
|
+
id_atend = rb_intern("@end");
|
215
|
+
id_atstart = rb_intern("@start");
|
216
|
+
id_atcaptures = rb_intern("@captures");
|
217
|
+
id_atsubject = rb_intern("@subject");
|
218
|
+
id_length = rb_intern("length");
|
219
|
+
id_has_key_p = rb_intern("has_key?");
|
220
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#ifndef _RUBY_GROKMATCH_H_
|
2
|
+
#define _RUBY_GROKMATCH_H_
|
3
|
+
|
4
|
+
#include "rgrok.h"
|
5
|
+
#include <grok.h>
|
6
|
+
|
7
|
+
#ifdef _IS_RUBY_GROKMATCH_
|
8
|
+
#define CONDEXTERN
|
9
|
+
#else
|
10
|
+
#define CONDEXTERN extern
|
11
|
+
#endif
|
12
|
+
|
13
|
+
CONDEXTERN VALUE rGrokMatch_new_from_grok_match(grok_match_t *gm);
|
14
|
+
#endif /* _RUBY_GROKMATCH_H_ */
|
Binary file
|
data/lib/grok.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "Grok"
|