re2 2.0.0.beta1-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ PACKAGE_ROOT_DIR = File.expand_path('../..', __dir__)
2
+ REQUIRED_MINI_PORTILE_VERSION = '~> 2.8.4' # keep this version in sync with the one in the gemspec
3
+
4
+ def build_recipe(name, version)
5
+ require 'rubygems'
6
+ gem('mini_portile2', REQUIRED_MINI_PORTILE_VERSION) # gemspec is not respected at install time
7
+ require 'mini_portile2'
8
+
9
+ MiniPortileCMake.new(name, version).tap do |recipe|
10
+ recipe.target = File.join(PACKAGE_ROOT_DIR, 'ports')
11
+ recipe.configure_options += [
12
+ # abseil needs a C++14 compiler
13
+ '-DCMAKE_CXX_STANDARD=17',
14
+ # needed for building the C extension shared library with -fPIC
15
+ '-DCMAKE_POSITION_INDEPENDENT_CODE=ON',
16
+ # ensures pkg-config and installed libraries will be in lib, not lib64
17
+ '-DCMAKE_INSTALL_LIBDIR=lib'
18
+ ]
19
+
20
+ yield recipe
21
+ end
22
+ end
23
+
24
+ def load_recipes
25
+ require 'yaml'
26
+ dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, 'dependencies.yml'))
27
+
28
+ abseil_recipe = build_recipe('abseil', dependencies['abseil']['version']) do |recipe|
29
+ recipe.files = [{
30
+ url: "https://github.com/abseil/abseil-cpp/archive/refs/tags/#{recipe.version}.tar.gz",
31
+ sha256: dependencies['abseil']['sha256']
32
+ }]
33
+ end
34
+
35
+ re2_recipe = build_recipe('libre2', dependencies['libre2']['version']) do |recipe|
36
+ recipe.files = [{
37
+ url: "https://github.com/google/re2/releases/download/#{recipe.version}/re2-#{recipe.version}.tar.gz",
38
+ sha256: dependencies['libre2']['sha256']
39
+ }]
40
+ end
41
+
42
+ [abseil_recipe, re2_recipe]
43
+ end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,15 @@
1
+ module RE2
2
+ class Scanner
3
+ include Enumerable
4
+
5
+ def each
6
+ if block_given?
7
+ while matches = scan
8
+ yield matches
9
+ end
10
+ else
11
+ to_enum(:each)
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/re2/string.rb ADDED
@@ -0,0 +1,85 @@
1
+ # re2 (http://github.com/mudge/re2)
2
+ # Ruby bindings to re2, an "efficient, principled regular expression library"
3
+ #
4
+ # Copyright (c) 2010-2014, Paul Mucur (http://mudge.name)
5
+ # Released under the BSD Licence, please see LICENSE.txt
6
+
7
+ require "re2"
8
+
9
+ module RE2
10
+ module String
11
+
12
+ # Replaces the first occurrence +pattern+ with +rewrite+ and returns a new
13
+ # string.
14
+ #
15
+ # @see RE2.Replace
16
+ def re2_sub(*args)
17
+ RE2.Replace(self, *args)
18
+ end
19
+
20
+ # Replaces every occurrence of +pattern+ with +rewrite+ and return a new string.
21
+ #
22
+ # @see RE2.GlobalReplace
23
+ def re2_gsub(*args)
24
+ RE2.GlobalReplace(self, *args)
25
+ end
26
+
27
+ # Match the pattern and return either a boolean (if no submatches are required)
28
+ # or a {RE2::MatchData} instance.
29
+ #
30
+ # @return [Boolean, RE2::MatchData]
31
+ #
32
+ # @overload match(pattern)
33
+ # Returns an {RE2::MatchData} containing the matching
34
+ # pattern and all subpatterns resulting from looking for
35
+ # +pattern+.
36
+ #
37
+ # @param [String, RE2::Regexp] pattern the regular expression to match
38
+ # @return [RE2::MatchData] the matches
39
+ # @raise [NoMemoryError] if there was not enough memory to allocate the matches
40
+ # @example
41
+ # r = RE2::Regexp.new('w(o)(o)')
42
+ # "woo".re2_match(r) #=> #<RE2::MatchData "woo" 1:"o" 2:"o">
43
+ #
44
+ # @overload match(pattern, 0)
45
+ # Returns either true or false indicating whether a
46
+ # successful match was made.
47
+ #
48
+ # @param [String, RE2::Regexp] pattern the regular expression to match
49
+ # @return [Boolean] whether the match was successful
50
+ # @raise [NoMemoryError] if there was not enough memory to allocate the matches
51
+ # @example
52
+ # r = RE2::Regexp.new('w(o)(o)')
53
+ # "woo".re2_match(0) #=> true
54
+ # "bob".re2_match(0) #=> false
55
+ #
56
+ # @overload match(pattern, number_of_matches)
57
+ # See +match(pattern)+ but with a specific number of
58
+ # matches returned (padded with nils if necessary).
59
+ #
60
+ # @param [String, RE2::Regexp] pattern the regular expression to match
61
+ # @param [Integer] number_of_matches the number of matches to return
62
+ # @return [RE2::MatchData] the matches
63
+ # @raise [NoMemoryError] if there was not enough memory to allocate the matches
64
+ # @example
65
+ # r = RE2::Regexp.new('w(o)(o)')
66
+ # "woo".re2_match(r, 1) #=> #<RE2::MatchData "woo" 1:"o">
67
+ # "woo".re2_match(r, 3) #=> #<RE2::MatchData "woo" 1:"o" 2:"o" 3:nil>
68
+ def re2_match(pattern, *args)
69
+ RE2::Regexp.new(pattern).match(self, *args)
70
+ end
71
+
72
+ # Escapes all potentially meaningful regexp characters.
73
+ # The returned string, used as a regular expression, will exactly match the
74
+ # original string.
75
+ #
76
+ # @return [String] the escaped string
77
+ # @example
78
+ # "1.5-2.0?".escape #=> "1\.5\-2\.0\?"
79
+ def re2_escape
80
+ RE2.QuoteMeta(self)
81
+ end
82
+
83
+ alias_method :re2_quote, :re2_escape
84
+ end
85
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RE2
4
+ VERSION = "2.0.0.beta1"
5
+ end
data/lib/re2.rb ADDED
@@ -0,0 +1,14 @@
1
+ # re2 (http://github.com/mudge/re2)
2
+ # Ruby bindings to re2, an "efficient, principled regular expression library"
3
+ #
4
+ # Copyright (c) 2010-2014, Paul Mucur (http://mudge.name)
5
+ # Released under the BSD Licence, please see LICENSE.txt
6
+ begin
7
+ ::RUBY_VERSION =~ /(\d+\.\d+)/
8
+ require_relative "#{Regexp.last_match(1)}/re2.so"
9
+ rescue LoadError
10
+ require 're2.so'
11
+ end
12
+
13
+ require "re2/scanner"
14
+ require "re2/version"
data/re2.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ require_relative 'lib/re2/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "re2"
5
+ s.summary = "Ruby bindings to re2."
6
+ s.description = 'Ruby bindings to re2, "an efficient, principled regular expression library".'
7
+ s.version = RE2::VERSION
8
+ s.authors = ["Paul Mucur"]
9
+ s.homepage = "https://github.com/mudge/re2"
10
+ s.extensions = ["ext/re2/extconf.rb"]
11
+ s.license = "BSD-3-Clause"
12
+ s.required_ruby_version = ">= 2.7.0"
13
+ s.files = [
14
+ ".rspec",
15
+ "dependencies.yml",
16
+ "ext/re2/extconf.rb",
17
+ "ext/re2/re2.cc",
18
+ "ext/re2/recipes.rb",
19
+ "Gemfile",
20
+ "lib/re2.rb",
21
+ "lib/re2/scanner.rb",
22
+ "lib/re2/string.rb",
23
+ "lib/re2/version.rb",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "re2.gemspec"
28
+ ]
29
+ s.test_files = [
30
+ "spec/spec_helper.rb",
31
+ "spec/re2_spec.rb",
32
+ "spec/kernel_spec.rb",
33
+ "spec/re2/regexp_spec.rb",
34
+ "spec/re2/match_data_spec.rb",
35
+ "spec/re2/string_spec.rb",
36
+ "spec/re2/set_spec.rb",
37
+ "spec/re2/scanner_spec.rb"
38
+ ]
39
+ s.add_development_dependency "rake-compiler", "~> 1.2.1"
40
+ s.add_development_dependency "rake-compiler-dock", "~> 1.3.0"
41
+ s.add_development_dependency("rspec", "~> 3.2")
42
+ s.add_runtime_dependency("mini_portile2", "~> 2.8.4") # keep version in sync with extconf.rb
43
+ end
@@ -0,0 +1,13 @@
1
+ RSpec.describe Kernel do
2
+ describe "#RE2" do
3
+ it "returns an RE2::Regexp instance given a pattern" do
4
+ expect(RE2('w(o)(o)')).to be_a(RE2::Regexp)
5
+ end
6
+
7
+ it "returns an RE2::Regexp instance given a pattern and options" do
8
+ re = RE2('w(o)(o)', :case_sensitive => false)
9
+ expect(re).to be_a(RE2::Regexp)
10
+ expect(re).to_not be_case_sensitive
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,302 @@
1
+ # encoding: utf-8
2
+ RSpec.describe RE2::MatchData do
3
+ describe "#to_a" do
4
+ it "is populated with the match and capturing groups" do
5
+ a = RE2::Regexp.new('w(o)(o)').match('woo').to_a
6
+ expect(a).to eq(["woo", "o", "o"])
7
+ end
8
+
9
+ it "populates optional capturing groups with nil if they are missing" do
10
+ a = RE2::Regexp.new('(\d?)(a)(b)').match('ab').to_a
11
+ expect(a).to eq(["ab", nil, "a", "b"])
12
+ end
13
+ end
14
+
15
+ describe "#[]" do
16
+ it "accesses capturing groups by numerical index" do
17
+ md = RE2::Regexp.new('(\d)(\d{2})').match("123")
18
+ expect(md[1]).to eq("1")
19
+ expect(md[2]).to eq("23")
20
+ end
21
+
22
+ it "has the whole match as the 0th item" do
23
+ md = RE2::Regexp.new('(\d)(\d{2})').match("123")
24
+ expect(md[0]).to eq("123")
25
+ end
26
+
27
+ it "supports access by numerical ranges" do
28
+ md = RE2::Regexp.new('(\d+) (\d+) (\d+)').match("123 456 789")
29
+ expect(md[1..3]).to eq(["123", "456", "789"])
30
+ expect(md[1...3]).to eq(["123", "456"])
31
+ end
32
+
33
+ it "supports slicing" do
34
+ md = RE2::Regexp.new('(\d+) (\d+) (\d+)').match("123 456 789")
35
+ expect(md[1, 3]).to eq(["123", "456", "789"])
36
+ expect(md[1, 2]).to eq(["123", "456"])
37
+ end
38
+
39
+ it "returns nil if attempting to access non-existent capturing groups by index" do
40
+ md = RE2::Regexp.new('(\d+)').match('bob 123')
41
+ expect(md[2]).to be_nil
42
+ expect(md[3]).to be_nil
43
+ end
44
+
45
+ it "allows access by string names when there are named groups" do
46
+ md = RE2::Regexp.new('(?P<numbers>\d+)').match('bob 123')
47
+ expect(md["numbers"]).to eq("123")
48
+ end
49
+
50
+ it "allows access by symbol names when there are named groups" do
51
+ md = RE2::Regexp.new('(?P<numbers>\d+)').match('bob 123')
52
+ expect(md[:numbers]).to eq("123")
53
+ end
54
+
55
+ it "allows access by names and indices with mixed groups" do
56
+ md = RE2::Regexp.new('(?P<name>\w+)(\s*)(?P<numbers>\d+)').match("bob 123")
57
+ expect(md["name"]).to eq("bob")
58
+ expect(md[:name]).to eq("bob")
59
+ expect(md[2]).to eq(" ")
60
+ expect(md["numbers"]).to eq("123")
61
+ expect(md[:numbers]).to eq("123")
62
+ end
63
+
64
+ it "returns nil if no such named group exists" do
65
+ md = RE2::Regexp.new('(\d+)').match("bob 123")
66
+ expect(md["missing"]).to be_nil
67
+ expect(md[:missing]).to be_nil
68
+ end
69
+
70
+ it "raises an error if given an inappropriate index" do
71
+ md = RE2::Regexp.new('(\d+)').match("bob 123")
72
+ expect { md[nil] }.to raise_error(TypeError)
73
+ end
74
+
75
+ if String.method_defined?(:encoding)
76
+ it "returns UTF-8 encoded strings by default" do
77
+ md = RE2::Regexp.new('(?P<name>\S+)').match("bob")
78
+ expect(md[0].encoding.name).to eq("UTF-8")
79
+ expect(md["name"].encoding.name).to eq("UTF-8")
80
+ expect(md[:name].encoding.name).to eq("UTF-8")
81
+ end
82
+
83
+ it "returns Latin 1 strings encoding when utf-8 is false" do
84
+ md = RE2::Regexp.new('(?P<name>\S+)', :utf8 => false).match('bob')
85
+ expect(md[0].encoding.name).to eq("ISO-8859-1")
86
+ expect(md["name"].encoding.name).to eq("ISO-8859-1")
87
+ expect(md[:name].encoding.name).to eq("ISO-8859-1")
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#string" do
93
+ it "returns the original string to match against" do
94
+ re = RE2::Regexp.new('(\D+)').match("bob")
95
+ expect(re.string).to eq("bob")
96
+ end
97
+
98
+ it "returns a copy, not the actual original" do
99
+ string = "bob"
100
+ re = RE2::Regexp.new('(\D+)').match(string)
101
+ expect(re.string).to_not equal(string)
102
+ end
103
+
104
+ it "returns a frozen string" do
105
+ re = RE2::Regexp.new('(\D+)').match("bob")
106
+ expect(re.string).to be_frozen
107
+ end
108
+ end
109
+
110
+ describe "#size" do
111
+ it "returns the number of capturing groups plus the matching string" do
112
+ md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
113
+ expect(md.size).to eq(3)
114
+ end
115
+ end
116
+
117
+ describe "#length" do
118
+ it "returns the number of capturing groups plus the matching string" do
119
+ md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
120
+ expect(md.length).to eq(3)
121
+ end
122
+ end
123
+
124
+ describe "#regexp" do
125
+ it "returns the original RE2::Regexp used" do
126
+ re = RE2::Regexp.new('(\d+)')
127
+ md = re.match("123")
128
+ expect(md.regexp).to equal(re)
129
+ end
130
+ end
131
+
132
+ describe "#inspect" do
133
+ it "returns a text representation of the object and indices" do
134
+ md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
135
+ expect(md.inspect).to eq('#<RE2::MatchData "1234 56" 1:"1234" 2:"56">')
136
+ end
137
+
138
+ it "represents missing matches as nil" do
139
+ md = RE2::Regexp.new('(\d+) (\d+)?').match("1234 ")
140
+ expect(md.inspect).to eq('#<RE2::MatchData "1234 " 1:"1234" 2:nil>')
141
+ end
142
+ end
143
+
144
+ describe "#to_s" do
145
+ it "returns the matching part of the original string" do
146
+ md = RE2::Regexp.new('(\d{2,5})').match("one two 23456")
147
+ expect(md.to_s).to eq("23456")
148
+ end
149
+ end
150
+
151
+ describe "#to_ary" do
152
+ it "allows the object to be expanded with an asterisk" do
153
+ md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
154
+ m1, m2, m3 = *md
155
+ expect(m1).to eq("1234 56")
156
+ expect(m2).to eq("1234")
157
+ expect(m3).to eq("56")
158
+ end
159
+ end
160
+
161
+ describe "#begin" do
162
+ it "returns the offset of the start of a match by index" do
163
+ md = RE2::Regexp.new('(wo{2})').match('a woohoo')
164
+ expect(md.string[md.begin(0)..-1]).to eq('woohoo')
165
+ end
166
+
167
+ it "returns the offset of the start of a match by string name" do
168
+ md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
169
+ expect(md.string[md.begin('foo')..-1]).to eq('foobar')
170
+ end
171
+
172
+ it "returns the offset of the start of a match by symbol name" do
173
+ md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
174
+ expect(md.string[md.begin(:foo)..-1]).to eq('foobar')
175
+ end
176
+
177
+ it "returns the offset despite multibyte characters" do
178
+ md = RE2::Regexp.new('(Ruby)').match('I ♥ Ruby')
179
+ expect(md.string[md.begin(0)..-1]).to eq('Ruby')
180
+ end
181
+
182
+ it "returns nil for non-existent numerical matches" do
183
+ md = RE2::Regexp.new('(\d)').match('123')
184
+ expect(md.begin(10)).to be_nil
185
+ end
186
+
187
+ it "returns nil for negative numerical matches" do
188
+ md = RE2::Regexp.new('(\d)').match('123')
189
+ expect(md.begin(-4)).to be_nil
190
+ end
191
+
192
+ it "returns nil for non-existent named matches" do
193
+ md = RE2::Regexp.new('(\d)').match('123')
194
+ expect(md.begin('foo')).to be_nil
195
+ end
196
+
197
+ it "returns nil for non-existent symbol named matches" do
198
+ md = RE2::Regexp.new('(\d)').match('123')
199
+ expect(md.begin(:foo)).to be_nil
200
+ end
201
+ end
202
+
203
+ describe "#end" do
204
+ it "returns the offset of the character following the end of a match" do
205
+ md = RE2::Regexp.new('(wo{2})').match('a woohoo')
206
+ expect(md.string[0...md.end(0)]).to eq('a woo')
207
+ end
208
+
209
+ it "returns the offset of a match by string name" do
210
+ md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
211
+ expect(md.string[0...md.end('foo')]).to eq('a foo')
212
+ end
213
+
214
+ it "returns the offset of a match by symbol name" do
215
+ md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
216
+ expect(md.string[0...md.end(:foo)]).to eq('a foo')
217
+ end
218
+
219
+ it "returns the offset despite multibyte characters" do
220
+ md = RE2::Regexp.new('(Ruby)').match('I ♥ Ruby')
221
+ expect(md.string[0...md.end(0)]).to eq('I ♥ Ruby')
222
+ end
223
+
224
+ it "returns nil for non-existent numerical matches" do
225
+ md = RE2::Regexp.new('(\d)').match('123')
226
+ expect(md.end(10)).to be_nil
227
+ end
228
+
229
+ it "returns nil for negative numerical matches" do
230
+ md = RE2::Regexp.new('(\d)').match('123')
231
+ expect(md.end(-4)).to be_nil
232
+ end
233
+
234
+ it "returns nil for non-existent named matches" do
235
+ md = RE2::Regexp.new('(\d)').match('123')
236
+ expect(md.end('foo')).to be_nil
237
+ end
238
+
239
+ it "returns nil for non-existent symbol named matches" do
240
+ md = RE2::Regexp.new('(\d)').match('123')
241
+ expect(md.end(:foo)).to be_nil
242
+ end
243
+ end
244
+
245
+ describe "#deconstruct" do
246
+ it "returns all capturing groups" do
247
+ md = RE2::Regexp.new('w(o)(o)').match('woo')
248
+
249
+ expect(md.deconstruct).to eq(['o', 'o'])
250
+ end
251
+
252
+ it "includes optional capturing groups as nil" do
253
+ md = RE2::Regexp.new('w(.)(.)(.)?').match('woo')
254
+
255
+ expect(md.deconstruct).to eq(['o', 'o', nil])
256
+ end
257
+ end
258
+
259
+ describe "#deconstruct_keys" do
260
+ it "returns all named captures if given nil" do
261
+ md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
262
+
263
+ expect(md.deconstruct_keys(nil)).to eq(:numbers => '123', :letters => 'abc')
264
+ end
265
+
266
+ it "returns only named captures if given names" do
267
+ md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
268
+
269
+ expect(md.deconstruct_keys([:numbers])).to eq(:numbers => '123')
270
+ end
271
+
272
+ it "returns named captures up until an invalid name is given" do
273
+ md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
274
+
275
+ expect(md.deconstruct_keys([:numbers, :punctuation])).to eq(:numbers => '123')
276
+ end
277
+
278
+ it "returns an empty hash if given more capture names than exist" do
279
+ md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
280
+
281
+ expect(md.deconstruct_keys([:numbers, :letters, :punctuation])).to eq({})
282
+ end
283
+
284
+ it "returns an empty hash if there are no named capturing groups" do
285
+ md = RE2::Regexp.new('(\d+) ([a-zA-Z]+)').match('123 abc')
286
+
287
+ expect(md.deconstruct_keys(nil)).to eq({})
288
+ end
289
+
290
+ it "raises an error if given a non-array of keys" do
291
+ md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
292
+
293
+ expect { md.deconstruct_keys(0) }.to raise_error(TypeError)
294
+ end
295
+
296
+ it "raises an error if given keys as non-symbols" do
297
+ md = RE2::Regexp.new('(?P<numbers>\d+) (?P<letters>[a-zA-Z]+)').match('123 abc')
298
+
299
+ expect { md.deconstruct_keys([0]) }.to raise_error(TypeError)
300
+ end
301
+ end
302
+ end