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.
Files changed (3) hide show
  1. data/ext/re2/re2.cc +109 -26
  2. data/test/re2_test.rb +36 -12
  3. 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
- typedef struct _re2p {
22
+ struct re2_pattern {
23
23
  RE2 *pattern;
24
- } re2_pattern;
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
- id_max_mem, id_literal, id_never_nl, id_case_sensitive,
31
- id_perl_classes, id_word_boundary, id_one_line;
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 = (re2_pattern*)malloc(sizeof(re2_pattern));
46
- p->pattern = NULL;
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(0);
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
- return BOOL2RUBY(p->pattern->Match(*text_as_string_piece, 0, RE2::UNANCHORED, 0, 0));
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
- if (rb_obj_is_kind_of(re, re2_cRE2)) {
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
- if (rb_obj_is_kind_of(re, re2_cRE2)) {
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
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-28 00:00:00 +01:00
18
+ date: 2010-07-29 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency