jls-grok 0.1.2786

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,7 @@
1
+ require "mkmf"
2
+ find_header("tcutil.h", "/usr/local/include")
3
+ find_header("pcre.h", "/usr/local/include")
4
+ find_header("grok.h", "../")
5
+ find_library("grok", "grok_init", "../")
6
+
7
+ create_makefile("Grok")
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
@@ -0,0 +1,9 @@
1
+ #ifndef _RGROK_H_
2
+ #define _RGROK_H_
3
+ #include <ruby.h>
4
+
5
+ //VALUE cGrok = Qnil;
6
+ //VALUE cGrokMatch = Qnil;
7
+
8
+ extern VALUE rGrok_new(VALUE klass);
9
+ #endif /* _RGROK_H_ */
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, &regexp, &regexplen);
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"