re2 0.7.0 → 1.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 32a2347d40362a3014dfd03f948405964468a3c2
4
- data.tar.gz: ea15968dae15568249200c6ba91bad66d0e28f6f
2
+ SHA256:
3
+ metadata.gz: b7a33f3c27224496ec131c261c7c66172f21474bce66cdf1cc1631c83040b3ca
4
+ data.tar.gz: 4d4a5448aa271bbce4cf37ffadfaadfa0797691fad5cc13f2f722e281116d66f
5
5
  SHA512:
6
- metadata.gz: 00588950e6c82fb5720043c04d0f833d819f3107a3c953f2284d9eaede74210c0c803f34b3e9fd89413c886fae1e4b853b5a85b18b3c2d788ff0a7e8b46036cf
7
- data.tar.gz: af2d23503d089a15ea6dd32e00bc80622cd7b0b1773ed471edcc982ac6791a6d1bf0bf5332d2440446796b5a4da15a169fd7396e3cf729af8a300e52a5985bad
6
+ metadata.gz: f080eccb20bb599b374485981f4c23fd8a49e84903ebe32e99e00b458c8b6334430cef41cbb1227fcba057f81d2fed4ead67648e506348fa6c2f975b7e6fea7f
7
+ data.tar.gz: bbd0ca07b287ca7e212175b4f5eaafd2698b7be94aefa432e81c4ff108b4b4c660e47d03d48d6affb82c0cee5f98fcb37bdcd97651bf309cebb148ac5e654518
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
- re2 [![Build Status](https://travis-ci.org/mudge/re2.svg?branch=master)](http://travis-ci.org/mudge/re2)
1
+ re2 [![Build Status](https://github.com/mudge/re2/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/mudge/re2/actions)
2
2
  ===
3
3
 
4
4
  A Ruby binding to [re2][], an "efficient, principled regular expression
5
5
  library".
6
6
 
7
- **Current version:** 0.7.0
8
- **Supported Ruby versions:** 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.0, Rubinius 2.2
7
+ **Current version:** 1.3.0
8
+ **Supported Ruby versions:** 1.8.7, 1.9.3, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0
9
+ **Supported re2 versions:** libre2.0 (< 2020-03-02), libre2.1 (2020-03-02), libre2.6 (2020-03-03), libre2.7 (2020-05-01), libre2.8 (2020-07-06), libre2.9 (2020-11-01)
9
10
 
10
11
  Installation
11
12
  ------------
@@ -21,13 +22,19 @@ If you are using Debian, you can install the [libre2-dev][] package like so:
21
22
 
22
23
  $ sudo apt-get install libre2-dev
23
24
 
25
+ Recent versions of re2 require a compiler with C++11 support such as [clang](http://clang.llvm.org/) 3.4 or [gcc](https://gcc.gnu.org/) 4.8.
26
+
24
27
  If you are using a packaged Ruby distribution, make sure you also have the
25
28
  Ruby header files installed such as those provided by the [ruby-dev][] package
26
29
  on Debian and Ubuntu.
27
30
 
28
31
  You can then install the library via RubyGems with `gem install re2` or `gem
29
- install re2 -- --with-re2-dir=/opt/local/re2` if re2 is not installed in the
30
- default location of `/usr/local/`.
32
+ install re2 -- --with-re2-dir=/path/to/re2/prefix` if re2 is not installed in
33
+ any of the following default locations:
34
+
35
+ * `/usr/local`
36
+ * `/opt/homebrew`
37
+ * `/usr`
31
38
 
32
39
  Documentation
33
40
  -------------
@@ -35,14 +42,17 @@ Documentation
35
42
  Full documentation automatically generated from the latest version is
36
43
  available at <http://mudge.name/re2/>.
37
44
 
38
- Bear in mind that re2's regular expression syntax differs from PCRE, see the
39
- [official syntax page][] for more details.
45
+ Note that re2's regular expression syntax differs from PCRE and Ruby's
46
+ built-in [`Regexp`][Regexp] library, see the [official syntax page][] for more
47
+ details.
40
48
 
41
49
  Usage
42
50
  -----
43
51
 
44
- You can use re2 as a mostly drop-in replacement for Ruby's own [Regexp][] and
45
- [MatchData][] classes:
52
+ While re2 uses the same naming scheme as Ruby's built-in regular expression
53
+ library (with [`Regexp`](http://mudge.name/re2/RE2/Regexp.html) and
54
+ [`MatchData`](http://mudge.name/re2/RE2/MatchData.html)), its API is slightly
55
+ different:
46
56
 
47
57
  ```console
48
58
  $ irb -rubygems
@@ -67,9 +77,11 @@ $ irb -rubygems
67
77
  => nil
68
78
  ```
69
79
 
70
- As `RE2::Regexp.new` (or `RE2::Regexp.compile`) can be quite verbose, a helper
71
- method has been defined against `Kernel` so you can use a shorter version to
72
- create regular expressions:
80
+ As
81
+ [`RE2::Regexp.new`](http://mudge.name/re2/RE2/Regexp.html#initialize-instance_method)
82
+ (or `RE2::Regexp.compile`) can be quite verbose, a helper method has been
83
+ defined against `Kernel` so you can use a shorter version to create regular
84
+ expressions:
73
85
 
74
86
  ```console
75
87
  > RE2('(\d+)')
@@ -123,7 +135,7 @@ Features
123
135
  --------
124
136
 
125
137
  * Pre-compiling regular expressions with
126
- [`RE2::Regexp.new(re)`](http://code.google.com/p/re2/source/browse/re2/re2.h#96),
138
+ [`RE2::Regexp.new(re)`](https://github.com/google/re2/blob/2016-02-01/re2/re2.h#L100),
127
139
  `RE2::Regexp.compile(re)` or `RE2(re)` (including specifying options, e.g.
128
140
  `RE2::Regexp.new("pattern", :case_sensitive => false)`
129
141
 
@@ -152,21 +164,25 @@ Features
152
164
  `pattern.replace_all(replacement, original)`
153
165
 
154
166
  * Escaping regular expressions with
155
- [`RE2.escape(unquoted)`](http://code.google.com/p/re2/source/browse/re2/re2.h#377) and
167
+ [`RE2.escape(unquoted)`](https://github.com/google/re2/blob/2016-02-01/re2/re2.h#L418) and
156
168
  `RE2.quote(unquoted)`
157
169
 
158
170
  Contributions
159
171
  -------------
160
172
 
161
- Thanks to [Jason Woods](https://github.com/driskell) who contributed the
162
- original implementations of `RE2::MatchData#begin` and `RE2::MatchData#end`.
173
+ * Thanks to [Jason Woods](https://github.com/driskell) who contributed the
174
+ original implementations of `RE2::MatchData#begin` and `RE2::MatchData#end`;
175
+ * Thanks to [Stefano Rivera](https://github.com/stefanor) who first contributed C++11 support;
176
+ * Thanks to [Stan Hu](https://github.com/stanhu) for reporting a bug with empty patterns and `RE2::Regexp#scan`;
177
+ * Thanks to [Sebastian Reitenbach](https://github.com/buzzdeee) for reporting
178
+ the deprecation and removal of the `utf8` encoding option in re2.
163
179
 
164
180
  Contact
165
181
  -------
166
182
 
167
- All feedback should go to the mailing list: <mailto:ruby.re2@librelist.com>
183
+ All issues and suggestions should go to [GitHub Issues](https://github.com/mudge/re2/issues).
168
184
 
169
- [re2]: http://code.google.com/p/re2/
185
+ [re2]: https://github.com/google/re2
170
186
  [gcc]: http://gcc.gnu.org/
171
187
  [ruby-dev]: http://packages.debian.org/ruby-dev
172
188
  [build-essential]: http://packages.debian.org/build-essential
@@ -174,5 +190,5 @@ All feedback should go to the mailing list: <mailto:ruby.re2@librelist.com>
174
190
  [MatchData]: http://ruby-doc.org/core/classes/MatchData.html
175
191
  [Homebrew]: http://mxcl.github.com/homebrew
176
192
  [libre2-dev]: http://packages.debian.org/search?keywords=libre2-dev
177
- [official syntax page]: http://code.google.com/p/re2/wiki/Syntax
193
+ [official syntax page]: https://github.com/google/re2/wiki/Syntax
178
194
 
data/Rakefile CHANGED
@@ -1,15 +1,10 @@
1
1
  require 'rake/extensiontask'
2
- require 'rake/testtask'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  Rake::ExtensionTask.new('re2')
5
5
 
6
- Rake::TestTask.new do |t|
7
- t.libs << "spec"
8
- t.test_files = FileList["spec/**/*_spec.rb"]
9
- t.verbose = true
10
- end
6
+ RSpec::Core::RakeTask.new(:spec)
11
7
 
12
- task :test => :compile
13
- task :spec => :test
14
- task :default => :test
8
+ task :spec => :compile
9
+ task :default => :spec
15
10
 
data/ext/re2/extconf.rb CHANGED
@@ -6,24 +6,72 @@
6
6
 
7
7
  require 'mkmf'
8
8
 
9
- incl, lib = dir_config("re2", "/usr/local/include", "/usr/local/lib")
9
+ if ENV["CC"]
10
+ RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
11
+ RbConfig::CONFIG["CC"] = ENV["CC"]
12
+ end
13
+
14
+ if ENV["CXX"]
15
+ RbConfig::MAKEFILE_CONFIG["CXX"] = ENV["CXX"]
16
+ RbConfig::CONFIG["CXX"] = ENV["CXX"]
17
+ end
18
+
19
+ header_dirs = [
20
+ "/usr/local/include",
21
+ "/opt/homebrew/include",
22
+ "/usr/include"
23
+ ]
24
+
25
+ lib_dirs = [
26
+ "/usr/local/lib",
27
+ "/opt/homebrew/lib",
28
+ "/usr/lib"
29
+ ]
30
+
31
+ dir_config("re2", header_dirs, lib_dirs)
10
32
 
11
33
  $CFLAGS << " -Wall -Wextra -funroll-loops"
12
34
 
35
+ # Pass -x c++ to force gcc to compile the test program
36
+ # as C++ (as it will end in .c by default).
37
+ compile_options = "-x c++"
38
+
13
39
  have_library("stdc++")
14
40
  have_header("stdint.h")
15
41
  have_func("rb_str_sublen")
16
42
 
17
- if have_library("re2")
43
+ unless have_library("re2")
44
+ abort "You must have re2 installed and specified with --with-re2-dir, please see https://github.com/google/re2/wiki/Install"
45
+ end
18
46
 
19
- # Determine which version of re2 the user has installed.
20
- # Revision d9f8806c004d added an `endpos` argument to the
21
- # generic Match() function.
22
- #
23
- # To test for this, try to compile a simple program that uses
24
- # the newer form of Match() and set a flag if it is successful.
25
- checking_for("RE2::Match() with endpos argument") do
26
- test_re2_match_signature = <<SRC
47
+ # Recent versions of re2 now require a compiler with C++11 support
48
+ checking_for("re2 requires C++11 compiler") do
49
+ minimal_program = <<SRC
50
+ #include <re2/re2.h>
51
+ int main() { return 0; }
52
+ SRC
53
+
54
+ unless try_compile(minimal_program, compile_options)
55
+ if try_compile(minimal_program, compile_options + " -std=c++11")
56
+ compile_options << " -std=c++11"
57
+ $CPPFLAGS << " -std=c++11"
58
+ elsif try_compile(minimal_program, compile_options + " -std=c++0x")
59
+ compile_options << " -std=c++0x"
60
+ $CPPFLAGS << " -std=c++0x"
61
+ else
62
+ abort "Cannot compile re2 with your compiler: recent versions require C++11 support."
63
+ end
64
+ end
65
+ end
66
+
67
+ # Determine which version of re2 the user has installed.
68
+ # Revision d9f8806c004d added an `endpos` argument to the
69
+ # generic Match() function.
70
+ #
71
+ # To test for this, try to compile a simple program that uses
72
+ # the newer form of Match() and set a flag if it is successful.
73
+ checking_for("RE2::Match() with endpos argument") do
74
+ test_re2_match_signature = <<SRC
27
75
  #include <re2/re2.h>
28
76
 
29
77
  int main() {
@@ -35,14 +83,9 @@ int main() {
35
83
  }
36
84
  SRC
37
85
 
38
- # Pass -x c++ to force gcc to compile the test program
39
- # as C++ (as it will end in .c by default).
40
- if try_compile(test_re2_match_signature, "-x c++")
41
- $defs.push("-DHAVE_ENDPOS_ARGUMENT")
42
- end
86
+ if try_compile(test_re2_match_signature, compile_options)
87
+ $defs.push("-DHAVE_ENDPOS_ARGUMENT")
43
88
  end
44
-
45
- create_makefile("re2")
46
- else
47
- abort "You must have re2 installed and specified with --with-re2-dir, please see http://code.google.com/p/re2/wiki/Install"
48
89
  end
90
+
91
+ create_makefile("re2")
data/ext/re2/re2.cc CHANGED
@@ -6,8 +6,8 @@
6
6
  * Released under the BSD Licence, please see LICENSE.txt
7
7
  */
8
8
 
9
- #include <re2/re2.h>
10
9
  #include <ruby.h>
10
+ #include <re2/re2.h>
11
11
  #include <stdint.h>
12
12
  #include <string>
13
13
  #include <sstream>
@@ -89,6 +89,7 @@ typedef struct {
89
89
  typedef struct {
90
90
  re2::StringPiece *input;
91
91
  int number_of_capturing_groups;
92
+ bool eof;
92
93
  VALUE regexp, text;
93
94
  } re2_scanner;
94
95
 
@@ -172,6 +173,21 @@ static VALUE re2_scanner_string(VALUE self) {
172
173
  return c->text;
173
174
  }
174
175
 
176
+ /*
177
+ * Returns whether the scanner has consumed all input or not.
178
+ *
179
+ * @return [Boolean] whether the scanner has consumed all input or not
180
+ * @example
181
+ * c = RE2::Regexp.new('(\d+)').scan("foo")
182
+ * c.eof? #=> true
183
+ */
184
+ static VALUE re2_scanner_eof(VALUE self) {
185
+ re2_scanner *c;
186
+ Data_Get_Struct(self, re2_scanner, c);
187
+
188
+ return BOOL2RUBY(c->eof);
189
+ }
190
+
175
191
  /*
176
192
  * Rewind the scanner to the start of the string.
177
193
  *
@@ -188,6 +204,7 @@ static VALUE re2_scanner_rewind(VALUE self) {
188
204
  Data_Get_Struct(self, re2_scanner, c);
189
205
 
190
206
  c->input = new(nothrow) re2::StringPiece(StringValuePtr(c->text));
207
+ c->eof = false;
191
208
 
192
209
  return self;
193
210
  }
@@ -204,6 +221,8 @@ static VALUE re2_scanner_rewind(VALUE self) {
204
221
  */
205
222
  static VALUE re2_scanner_scan(VALUE self) {
206
223
  int i;
224
+ size_t original_input_size, new_input_size;
225
+ bool input_advanced;
207
226
  re2_pattern *p;
208
227
  re2_scanner *c;
209
228
  VALUE result;
@@ -215,6 +234,12 @@ static VALUE re2_scanner_scan(VALUE self) {
215
234
  vector<RE2::Arg*> args(c->number_of_capturing_groups);
216
235
  vector<string> matches(c->number_of_capturing_groups);
217
236
 
237
+ if (c->eof) {
238
+ return Qnil;
239
+ }
240
+
241
+ original_input_size = c->input->size();
242
+
218
243
  for (i = 0; i < c->number_of_capturing_groups; i++) {
219
244
  matches[i] = "";
220
245
  argv[i] = &matches[i];
@@ -224,15 +249,26 @@ static VALUE re2_scanner_scan(VALUE self) {
224
249
  if (RE2::FindAndConsumeN(c->input, *p->pattern, &args[0],
225
250
  c->number_of_capturing_groups)) {
226
251
  result = rb_ary_new2(c->number_of_capturing_groups);
252
+ new_input_size = c->input->size();
253
+ input_advanced = new_input_size < original_input_size;
254
+
227
255
  for (i = 0; i < c->number_of_capturing_groups; i++) {
228
256
  if (matches[i].empty()) {
229
257
  rb_ary_push(result, Qnil);
230
258
  } else {
231
259
  rb_ary_push(result, ENCODED_STR_NEW(matches[i].data(),
232
260
  matches[i].size(),
233
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1"));
261
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1"));
234
262
  }
235
263
  }
264
+
265
+ /* Check whether we've exhausted the input yet. */
266
+ c->eof = new_input_size == 0;
267
+
268
+ /* If the match didn't advance the input, we need to do this ourselves. */
269
+ if (!input_advanced && new_input_size > 0) {
270
+ c->input->remove_prefix(1);
271
+ }
236
272
  } else {
237
273
  result = Qnil;
238
274
  }
@@ -325,7 +361,7 @@ static VALUE re2_matchdata_begin(VALUE self, VALUE n) {
325
361
  offset = reinterpret_cast<uintptr_t>(match->data()) - reinterpret_cast<uintptr_t>(StringValuePtr(m->text));
326
362
 
327
363
  return ENCODED_STR_SUBLEN(StringValue(m->text), offset,
328
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
364
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
329
365
  }
330
366
  }
331
367
 
@@ -356,7 +392,7 @@ static VALUE re2_matchdata_end(VALUE self, VALUE n) {
356
392
  offset = reinterpret_cast<uintptr_t>(match->data()) - reinterpret_cast<uintptr_t>(StringValuePtr(m->text)) + match->size();
357
393
 
358
394
  return ENCODED_STR_SUBLEN(StringValue(m->text), offset,
359
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
395
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
360
396
  }
361
397
  }
362
398
 
@@ -420,7 +456,7 @@ static VALUE re2_matchdata_to_a(VALUE self) {
420
456
  rb_ary_push(array, Qnil);
421
457
  } else {
422
458
  rb_ary_push(array, ENCODED_STR_NEW(match->data(), match->size(),
423
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1"));
459
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1"));
424
460
  }
425
461
  }
426
462
 
@@ -444,7 +480,7 @@ static VALUE re2_matchdata_nth_match(int nth, VALUE self) {
444
480
  return Qnil;
445
481
  } else {
446
482
  return ENCODED_STR_NEW(match->data(), match->size(),
447
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
483
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
448
484
  }
449
485
  }
450
486
  }
@@ -575,7 +611,7 @@ static VALUE re2_matchdata_inspect(VALUE self) {
575
611
  output << ">";
576
612
 
577
613
  result = ENCODED_STR_NEW(output.str().data(), output.str().length(),
578
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
614
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
579
615
 
580
616
  return result;
581
617
  }
@@ -648,7 +684,7 @@ static VALUE re2_regexp_initialize(int argc, VALUE *argv, VALUE self) {
648
684
 
649
685
  utf8 = rb_hash_aref(options, ID2SYM(id_utf8));
650
686
  if (!NIL_P(utf8)) {
651
- re2_options.set_utf8(RTEST(utf8));
687
+ re2_options.set_encoding(RTEST(utf8) ? RE2::Options::EncodingUTF8 : RE2::Options::EncodingLatin1);
652
688
  }
653
689
 
654
690
  posix_syntax = rb_hash_aref(options, ID2SYM(id_posix_syntax));
@@ -731,7 +767,7 @@ static VALUE re2_regexp_inspect(VALUE self) {
731
767
  output << "#<RE2::Regexp /" << p->pattern->pattern() << "/>";
732
768
 
733
769
  result = ENCODED_STR_NEW(output.str().data(), output.str().length(),
734
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
770
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
735
771
 
736
772
  return result;
737
773
  }
@@ -749,7 +785,7 @@ static VALUE re2_regexp_to_s(VALUE self) {
749
785
  Data_Get_Struct(self, re2_pattern, p);
750
786
  return ENCODED_STR_NEW(p->pattern->pattern().data(),
751
787
  p->pattern->pattern().size(),
752
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
788
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
753
789
  }
754
790
 
755
791
  /*
@@ -779,7 +815,7 @@ static VALUE re2_regexp_ok(VALUE self) {
779
815
  static VALUE re2_regexp_utf8(VALUE self) {
780
816
  re2_pattern *p;
781
817
  Data_Get_Struct(self, re2_pattern, p);
782
- return BOOL2RUBY(p->pattern->options().utf8());
818
+ return BOOL2RUBY(p->pattern->options().encoding() == RE2::Options::EncodingUTF8);
783
819
  }
784
820
 
785
821
  /*
@@ -976,7 +1012,7 @@ static VALUE re2_regexp_error_arg(VALUE self) {
976
1012
  } else {
977
1013
  return ENCODED_STR_NEW(p->pattern->error_arg().data(),
978
1014
  p->pattern->error_arg().size(),
979
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
1015
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
980
1016
  }
981
1017
  }
982
1018
 
@@ -1007,7 +1043,7 @@ static VALUE re2_regexp_options(VALUE self) {
1007
1043
  options = rb_hash_new();
1008
1044
 
1009
1045
  rb_hash_aset(options, ID2SYM(id_utf8),
1010
- BOOL2RUBY(p->pattern->options().utf8()));
1046
+ BOOL2RUBY(p->pattern->options().encoding() == RE2::Options::EncodingUTF8));
1011
1047
 
1012
1048
  rb_hash_aset(options, ID2SYM(id_posix_syntax),
1013
1049
  BOOL2RUBY(p->pattern->options().posix_syntax()));
@@ -1077,7 +1113,7 @@ static VALUE re2_regexp_named_capturing_groups(VALUE self) {
1077
1113
  for (iterator = groups.begin(); iterator != groups.end(); iterator++) {
1078
1114
  rb_hash_aset(capturing_groups,
1079
1115
  ENCODED_STR_NEW(iterator->first.data(), iterator->first.size(),
1080
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1"),
1116
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1"),
1081
1117
  INT2FIX(iterator->second));
1082
1118
  }
1083
1119
 
@@ -1216,6 +1252,7 @@ static VALUE re2_regexp_scan(VALUE self, VALUE text) {
1216
1252
  c->regexp = self;
1217
1253
  c->text = text;
1218
1254
  c->number_of_capturing_groups = p->pattern->NumberOfCapturingGroups();
1255
+ c->eof = false;
1219
1256
 
1220
1257
  return scanner;
1221
1258
  }
@@ -1247,7 +1284,7 @@ static VALUE re2_Replace(VALUE self, VALUE str, VALUE pattern,
1247
1284
  RE2::Replace(&str_as_string, *p->pattern, StringValuePtr(rewrite));
1248
1285
 
1249
1286
  return ENCODED_STR_NEW(str_as_string.data(), str_as_string.size(),
1250
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
1287
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
1251
1288
  } else {
1252
1289
  RE2::Replace(&str_as_string, StringValuePtr(pattern),
1253
1290
  StringValuePtr(rewrite));
@@ -1284,7 +1321,7 @@ static VALUE re2_GlobalReplace(VALUE self, VALUE str, VALUE pattern,
1284
1321
  RE2::GlobalReplace(&str_as_string, *p->pattern, StringValuePtr(rewrite));
1285
1322
 
1286
1323
  return ENCODED_STR_NEW(str_as_string.data(), str_as_string.size(),
1287
- p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1");
1324
+ p->pattern->options().encoding() == RE2::Options::EncodingUTF8 ? "UTF-8" : "ISO-8859-1");
1288
1325
  } else {
1289
1326
  RE2::GlobalReplace(&str_as_string, StringValuePtr(pattern),
1290
1327
  StringValuePtr(rewrite));
@@ -1349,6 +1386,8 @@ void Init_re2(void) {
1349
1386
 
1350
1387
  rb_define_method(re2_cScanner, "string",
1351
1388
  RUBY_METHOD_FUNC(re2_scanner_string), 0);
1389
+ rb_define_method(re2_cScanner, "eof?",
1390
+ RUBY_METHOD_FUNC(re2_scanner_eof), 0);
1352
1391
  rb_define_method(re2_cScanner, "regexp",
1353
1392
  RUBY_METHOD_FUNC(re2_scanner_regexp), 0);
1354
1393
  rb_define_method(re2_cScanner, "scan",