re2 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/re2/re2.cc +109 -26
- data/test/re2_test.rb +36 -12
- metadata +4 -4
data/ext/re2/re2.cc
CHANGED
@@ -19,16 +19,16 @@ extern "C" {
|
|
19
19
|
# define RSTRING_LEN(x) (RSTRING(x)->len)
|
20
20
|
#endif
|
21
21
|
|
22
|
-
|
22
|
+
struct re2_pattern {
|
23
23
|
RE2 *pattern;
|
24
|
-
}
|
24
|
+
};
|
25
25
|
|
26
26
|
VALUE re2_cRE2;
|
27
27
|
|
28
28
|
/* Symbols used in RE2 options. */
|
29
29
|
static ID id_utf8, id_posix_syntax, id_longest_match, id_log_errors,
|
30
|
-
|
31
|
-
|
30
|
+
id_max_mem, id_literal, id_never_nl, id_case_sensitive,
|
31
|
+
id_perl_classes, id_word_boundary, id_one_line;
|
32
32
|
|
33
33
|
void
|
34
34
|
re2_free(re2_pattern* self)
|
@@ -42,9 +42,8 @@ extern "C" {
|
|
42
42
|
static VALUE
|
43
43
|
re2_allocate(VALUE klass)
|
44
44
|
{
|
45
|
-
re2_pattern *p
|
46
|
-
|
47
|
-
return Data_Wrap_Struct(klass, 0, re2_free, p);
|
45
|
+
re2_pattern *p;
|
46
|
+
return Data_Make_Struct(klass, re2_pattern, 0, re2_free, p);
|
48
47
|
}
|
49
48
|
|
50
49
|
/*
|
@@ -124,7 +123,11 @@ extern "C" {
|
|
124
123
|
rb_raise(rb_eArgError, "options should be a hash");
|
125
124
|
}
|
126
125
|
|
127
|
-
re2_options = new RE2::Options();
|
126
|
+
re2_options = new (std::nothrow) RE2::Options();
|
127
|
+
|
128
|
+
if (re2_options == 0) {
|
129
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate RE2::Options");
|
130
|
+
}
|
128
131
|
|
129
132
|
utf8 = rb_hash_aref(options, ID2SYM(id_utf8));
|
130
133
|
if (!NIL_P(utf8)) {
|
@@ -181,9 +184,13 @@ extern "C" {
|
|
181
184
|
re2_options->set_one_line(RTEST(one_line));
|
182
185
|
}
|
183
186
|
|
184
|
-
p->pattern = new RE2(StringValuePtr(pattern), *re2_options);
|
187
|
+
p->pattern = new (std::nothrow) RE2(StringValuePtr(pattern), *re2_options);
|
185
188
|
} else {
|
186
|
-
p->pattern = new RE2(StringValuePtr(pattern));
|
189
|
+
p->pattern = new (std::nothrow) RE2(StringValuePtr(pattern));
|
190
|
+
}
|
191
|
+
|
192
|
+
if (p->pattern == 0) {
|
193
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object");
|
187
194
|
}
|
188
195
|
|
189
196
|
return self;
|
@@ -202,7 +209,7 @@ extern "C" {
|
|
202
209
|
static VALUE
|
203
210
|
re2_inspect(VALUE self)
|
204
211
|
{
|
205
|
-
VALUE result = rb_str_buf_new(
|
212
|
+
VALUE result = rb_str_buf_new(2);
|
206
213
|
re2_pattern *p;
|
207
214
|
|
208
215
|
rb_str_buf_cat2(result, "/");
|
@@ -624,19 +631,34 @@ extern "C" {
|
|
624
631
|
n = p->pattern->NumberOfCapturingGroups();
|
625
632
|
}
|
626
633
|
|
627
|
-
text_as_string_piece = new re2::StringPiece(StringValuePtr(text));
|
634
|
+
text_as_string_piece = new (std::nothrow) re2::StringPiece(StringValuePtr(text));
|
635
|
+
|
636
|
+
if (text_as_string_piece == 0) {
|
637
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate StringPiece for text");
|
638
|
+
}
|
628
639
|
|
629
640
|
if (n == 0) {
|
630
|
-
|
641
|
+
matched = p->pattern->Match(*text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
|
642
|
+
|
643
|
+
delete text_as_string_piece;
|
644
|
+
|
645
|
+
return BOOL2RUBY(matched);
|
646
|
+
|
631
647
|
} else {
|
632
648
|
|
633
649
|
/* Because match returns the whole match as well. */
|
634
650
|
n += 1;
|
635
651
|
|
636
|
-
string_matches = new re2::StringPiece[n];
|
652
|
+
string_matches = new (std::nothrow) re2::StringPiece[n];
|
653
|
+
|
654
|
+
if (string_matches == 0) {
|
655
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of StringPieces for matches");
|
656
|
+
}
|
637
657
|
|
638
658
|
matched = p->pattern->Match(*text_as_string_piece, 0, RE2::UNANCHORED, string_matches, n);
|
639
659
|
|
660
|
+
delete text_as_string_piece;
|
661
|
+
|
640
662
|
if (matched) {
|
641
663
|
matches = rb_ary_new();
|
642
664
|
|
@@ -648,8 +670,13 @@ extern "C" {
|
|
648
670
|
}
|
649
671
|
}
|
650
672
|
|
673
|
+
delete[] string_matches;
|
674
|
+
|
651
675
|
return matches;
|
652
676
|
} else {
|
677
|
+
|
678
|
+
delete[] string_matches;
|
679
|
+
|
653
680
|
return Qnil;
|
654
681
|
}
|
655
682
|
}
|
@@ -729,7 +756,7 @@ extern "C" {
|
|
729
756
|
{
|
730
757
|
UNUSED(self);
|
731
758
|
int n;
|
732
|
-
bool matched;
|
759
|
+
bool matched, re2_given;
|
733
760
|
re2_pattern *p;
|
734
761
|
VALUE matches;
|
735
762
|
RE2 *compiled_pattern;
|
@@ -737,18 +764,36 @@ extern "C" {
|
|
737
764
|
const RE2::Arg **args;
|
738
765
|
std::string *string_matches;
|
739
766
|
|
740
|
-
|
767
|
+
re2_given = rb_obj_is_kind_of(re, re2_cRE2);
|
768
|
+
|
769
|
+
if (re2_given) {
|
741
770
|
Data_Get_Struct(re, re2_pattern, p);
|
742
771
|
compiled_pattern = p->pattern;
|
743
772
|
} else {
|
744
|
-
compiled_pattern = new RE2(StringValuePtr(re));
|
773
|
+
compiled_pattern = new (std::nothrow) RE2(StringValuePtr(re));
|
774
|
+
|
775
|
+
if (compiled_pattern == 0) {
|
776
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object for pattern");
|
777
|
+
}
|
745
778
|
}
|
746
779
|
|
747
780
|
n = compiled_pattern->NumberOfCapturingGroups();
|
748
781
|
|
749
|
-
argv = new RE2::Arg[n];
|
750
|
-
args = new const RE2::Arg*[n];
|
751
|
-
string_matches = new std::string[n];
|
782
|
+
argv = new (std::nothrow) RE2::Arg[n];
|
783
|
+
args = new (std::nothrow) const RE2::Arg*[n];
|
784
|
+
string_matches = new (std::nothrow) std::string[n];
|
785
|
+
|
786
|
+
if (argv == 0) {
|
787
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of RE2::Args");
|
788
|
+
}
|
789
|
+
|
790
|
+
if (args == 0) {
|
791
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of pointers to RE2::Args");
|
792
|
+
}
|
793
|
+
|
794
|
+
if (string_matches == 0) {
|
795
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of strings for matches");
|
796
|
+
}
|
752
797
|
|
753
798
|
for (int i = 0; i < n; i++) {
|
754
799
|
args[i] = &argv[i];
|
@@ -757,6 +802,13 @@ extern "C" {
|
|
757
802
|
|
758
803
|
matched = RE2::FullMatchN(StringValuePtr(text), *compiled_pattern, args, n);
|
759
804
|
|
805
|
+
if (!re2_given) {
|
806
|
+
delete compiled_pattern;
|
807
|
+
}
|
808
|
+
|
809
|
+
delete[] argv;
|
810
|
+
delete[] args;
|
811
|
+
|
760
812
|
if (matched) {
|
761
813
|
matches = rb_ary_new();
|
762
814
|
|
@@ -768,8 +820,11 @@ extern "C" {
|
|
768
820
|
}
|
769
821
|
}
|
770
822
|
|
823
|
+
delete[] string_matches;
|
824
|
+
|
771
825
|
return matches;
|
772
826
|
} else {
|
827
|
+
delete[] string_matches;
|
773
828
|
return Qnil;
|
774
829
|
}
|
775
830
|
}
|
@@ -788,7 +843,7 @@ extern "C" {
|
|
788
843
|
{
|
789
844
|
UNUSED(self);
|
790
845
|
int n;
|
791
|
-
bool matched;
|
846
|
+
bool matched, re2_given;
|
792
847
|
re2_pattern *p;
|
793
848
|
VALUE matches;
|
794
849
|
RE2 *compiled_pattern;
|
@@ -796,18 +851,36 @@ extern "C" {
|
|
796
851
|
const RE2::Arg **args;
|
797
852
|
std::string *string_matches;
|
798
853
|
|
799
|
-
|
854
|
+
re2_given = rb_obj_is_kind_of(re, re2_cRE2);
|
855
|
+
|
856
|
+
if (re2_given) {
|
800
857
|
Data_Get_Struct(re, re2_pattern, p);
|
801
858
|
compiled_pattern = p->pattern;
|
802
859
|
} else {
|
803
|
-
compiled_pattern = new RE2(StringValuePtr(re));
|
860
|
+
compiled_pattern = new (std::nothrow) RE2(StringValuePtr(re));
|
861
|
+
|
862
|
+
if (compiled_pattern == 0) {
|
863
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate RE2 object for pattern");
|
864
|
+
}
|
804
865
|
}
|
805
866
|
|
806
867
|
n = compiled_pattern->NumberOfCapturingGroups();
|
807
868
|
|
808
|
-
argv = new RE2::Arg[n];
|
809
|
-
args = new const RE2::Arg*[n];
|
810
|
-
string_matches = new std::string[n];
|
869
|
+
argv = new (std::nothrow) RE2::Arg[n];
|
870
|
+
args = new (std::nothrow) const RE2::Arg*[n];
|
871
|
+
string_matches = new (std::nothrow) std::string[n];
|
872
|
+
|
873
|
+
if (argv == 0) {
|
874
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of RE2::Args");
|
875
|
+
}
|
876
|
+
|
877
|
+
if (args == 0) {
|
878
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of pointers to RE2::Args");
|
879
|
+
}
|
880
|
+
|
881
|
+
if (string_matches == 0) {
|
882
|
+
rb_raise(rb_eNoMemError, "not enough memory to allocate array of strings for matches");
|
883
|
+
}
|
811
884
|
|
812
885
|
for (int i = 0; i < n; i++) {
|
813
886
|
args[i] = &argv[i];
|
@@ -816,6 +889,13 @@ extern "C" {
|
|
816
889
|
|
817
890
|
matched = RE2::PartialMatchN(StringValuePtr(text), *compiled_pattern, args, n);
|
818
891
|
|
892
|
+
if (!re2_given) {
|
893
|
+
delete compiled_pattern;
|
894
|
+
}
|
895
|
+
|
896
|
+
delete[] argv;
|
897
|
+
delete[] args;
|
898
|
+
|
819
899
|
if (matched) {
|
820
900
|
matches = rb_ary_new();
|
821
901
|
|
@@ -827,8 +907,11 @@ extern "C" {
|
|
827
907
|
}
|
828
908
|
}
|
829
909
|
|
910
|
+
delete[] string_matches;
|
911
|
+
|
830
912
|
return matches;
|
831
913
|
} else {
|
914
|
+
delete[] string_matches;
|
832
915
|
return Qnil;
|
833
916
|
}
|
834
917
|
}
|
data/test/re2_test.rb
CHANGED
@@ -74,6 +74,18 @@ class RE2Test < Test::Unit::TestCase
|
|
74
74
|
assert !RE2::FullMatch("woo", "wowzer")
|
75
75
|
end
|
76
76
|
|
77
|
+
def test_full_match_with_compiled_pattern
|
78
|
+
r = RE2.new("woo")
|
79
|
+
assert RE2::FullMatch("woo", r)
|
80
|
+
assert !RE2::FullMatch("wowzer", r)
|
81
|
+
|
82
|
+
assert RE2::FullMatch("woo", RE2("woo"))
|
83
|
+
assert RE2::FullMatch("woo", RE2("wo+"))
|
84
|
+
assert RE2::FullMatch("woo", RE2("woo?"))
|
85
|
+
assert RE2::FullMatch("woo", RE2("wo{2}"))
|
86
|
+
assert !RE2::FullMatch("woo", RE2("wowzer"))
|
87
|
+
end
|
88
|
+
|
77
89
|
def test_full_match_n
|
78
90
|
assert_equal ["oo"], RE2::FullMatchN("woo", "w(oo)")
|
79
91
|
assert_equal ["12"], RE2::FullMatchN("woo12w", 'woo(\d{2})w')
|
@@ -95,6 +107,17 @@ class RE2Test < Test::Unit::TestCase
|
|
95
107
|
assert !RE2::PartialMatch("woo", "ha")
|
96
108
|
end
|
97
109
|
|
110
|
+
def test_partial_match_with_compiled_pattern
|
111
|
+
r = RE2.new("woo")
|
112
|
+
assert RE2::PartialMatch("woo", r)
|
113
|
+
assert !RE2::PartialMatch("wowzer", r)
|
114
|
+
|
115
|
+
assert RE2::PartialMatch("woo", RE2("oo"))
|
116
|
+
assert RE2::PartialMatch("woo", RE2("oo?"))
|
117
|
+
assert RE2::PartialMatch("woo", RE2("o{2}"))
|
118
|
+
assert !RE2::PartialMatch("woo", RE2("ha"))
|
119
|
+
end
|
120
|
+
|
98
121
|
def test_partial_match_n
|
99
122
|
assert_equal ["oo"], RE2::PartialMatchN("awooa", "w(oo)")
|
100
123
|
assert_equal ["12"], RE2::PartialMatchN("awoo12wa", 'woo(\d{2})w')
|
@@ -170,6 +193,9 @@ class RE2Test < Test::Unit::TestCase
|
|
170
193
|
assert_equal ["woo", "o"], RE2.new('w(o)(o)').match('woo', 1)
|
171
194
|
assert_equal ["woo", "o", "o"], RE2.new('w(o)(o)').match('woo', 2)
|
172
195
|
assert_equal ["woo", "o", "o", nil], RE2.new('w(o)(o)').match('woo', 3)
|
196
|
+
assert_equal ["w", nil], RE2.new('w(o)?(o)?').match('w', 1)
|
197
|
+
assert_equal ["w", nil, nil], RE2.new('w(o)?(o)?').match('w', 2)
|
198
|
+
assert_equal ["w", nil, nil, nil], RE2.new('w(o)?(o)?').match('w', 3)
|
173
199
|
end
|
174
200
|
|
175
201
|
def test_compiling_with_options
|
@@ -185,26 +211,24 @@ class RE2Test < Test::Unit::TestCase
|
|
185
211
|
assert r.options[:utf8]
|
186
212
|
end
|
187
213
|
|
188
|
-
def test_full_match_with_re2
|
189
|
-
r = RE2.new("woo")
|
190
|
-
assert RE2::FullMatch("woo", r)
|
191
|
-
assert !RE2::FullMatch("wowzer", r)
|
192
|
-
end
|
193
|
-
|
194
|
-
def test_partial_match_with_re2
|
195
|
-
r = RE2.new("woo")
|
196
|
-
assert RE2::PartialMatch("woo", r)
|
197
|
-
assert !RE2::PartialMatch("wowzer", r)
|
198
|
-
end
|
199
|
-
|
200
214
|
def test_replace_with_re2
|
201
215
|
r = RE2.new("wo{2}")
|
202
216
|
assert_equal "miaow", RE2::Replace("woo", r, "miaow")
|
217
|
+
|
218
|
+
assert_equal "wao", RE2::Replace("woo", RE2("o"), "a")
|
219
|
+
assert_equal "hoo", RE2::Replace("woo", RE2("w"), "h")
|
220
|
+
assert_equal "we", RE2::Replace("woo", RE2("o+"), "e")
|
221
|
+
assert_equal "Good morning", RE2::Replace("hi", RE2("hih?"), "Good morning")
|
222
|
+
assert_equal "hi", RE2::Replace("Good morning", RE2("gOOD MORNING", :case_sensitive => false), "hi")
|
203
223
|
end
|
204
224
|
|
205
225
|
def test_global_replace_with_re2
|
206
226
|
r = RE2.new("o")
|
207
227
|
assert_equal "wii", RE2::GlobalReplace("woo", r, "i")
|
228
|
+
|
229
|
+
assert_equal "waa", RE2::GlobalReplace("woo", RE2("o"), "a")
|
230
|
+
assert_equal "hoo", RE2::GlobalReplace("woo", RE2("w"), "h")
|
231
|
+
assert_equal "we", RE2::GlobalReplace("woo", RE2("o+"), "e")
|
208
232
|
end
|
209
233
|
|
210
234
|
def test_quote_meta
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: re2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Paul Mucur
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-29 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|