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 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"