re2 0.0.2 → 0.0.3
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/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
|