Skip to content

Commit

Permalink
MatchData: fixed crystal-lang#4565: rename size to group_size and fix…
Browse files Browse the repository at this point in the history
… size behavior
  • Loading branch information
makenowjust committed Jun 14, 2017
1 parent 526837e commit 9bc5302
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
6 changes: 6 additions & 0 deletions spec/std/match_data_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ describe "Regex::MatchData" do
/fox/.match("the fox").to_s.should eq(%(#<Regex::MatchData "fox">))
end

it "does size" do
"Crystal".match(/[p-s]/).not_nil!.size.should eq(1)
"Crystal".match(/r(ys)/).not_nil!.size.should eq(2)
"Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.size.should eq(3)
end

describe "#[]" do
it "captures empty group" do
("foo" =~ /(?<g1>z?)foo/).should eq(0)
Expand Down
42 changes: 26 additions & 16 deletions src/regex/match_data.cr
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class Regex
# Returns the number of capture groups, including named capture groups.
#
# ```
# "Crystal".match(/[p-s]/).not_nil!.size # => 0
# "Crystal".match(/r(ys)/).not_nil!.size # => 1
# "Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.size # => 2
# "Crystal".match(/[p-s]/).not_nil!.group_size # => 0
# "Crystal".match(/r(ys)/).not_nil!.group_size # => 1
# "Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.group_size # => 2
# ```
getter size : Int32
getter group_size : Int32

# Returns the original string.
#
Expand All @@ -40,7 +40,18 @@ class Regex
getter string : String

# :nodoc:
def initialize(@regex : Regex, @code : LibPCRE::Pcre, @string : String, @pos : Int32, @ovector : Int32*, @size : Int32)
def initialize(@regex : Regex, @code : LibPCRE::Pcre, @string : String, @pos : Int32, @ovector : Int32*, @group_size : Int32)
end

# Returns the number of elements in this match object.
#
# ```
# "Crystal".match(/[p-s]/).not_nil!.size # => 1
# "Crystal".match(/r(ys)/).not_nil!.size # => 2
# "Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.size # => 3
# ```
def size
group_size + 1
end

# Return the position of the first character of the *n*th match.
Expand Down Expand Up @@ -204,7 +215,7 @@ class Regex
name_table = @regex.name_table

caps = [] of String?
(1..size).each do |i|
(1...size).each do |i|
caps << self[i]? unless name_table.has_key? i
end

Expand All @@ -226,7 +237,7 @@ class Regex
name_table = @regex.name_table

caps = {} of String => String?
(1..size).each do |i|
(1...size).each do |i|
if name = name_table[i]?
caps[name] = self[i]?
end
Expand All @@ -247,7 +258,7 @@ class Regex
# match.to_a # => ["Cr", "Cr", nil]
# ```
def to_a
(0..size).map { |i| self[i]? }
(0...size).map { |i| self[i]? }
end

# Convert this match data into a hash.
Expand All @@ -265,7 +276,7 @@ class Regex
name_table = @regex.name_table

hash = {} of (String | Int32) => String?
(0..size).each do |i|
(0...size).each do |i|
hash[name_table.fetch(i) { i }] = self[i]?
end

Expand All @@ -281,13 +292,12 @@ class Regex

io << "#<Regex::MatchData "
self[0].inspect(io)
if size > 0
if size > 1
io << " "
size.times do |i|
io << " " if i > 0
io << name_table.fetch(i + 1) { i + 1 }
(1...size).join " ", io do |i|
io << name_table.fetch(i) { i }
io << ":"
self[i + 1]?.inspect(io)
self[i]?.inspect(io)
end
end
io << ">"
Expand All @@ -306,15 +316,15 @@ class Regex
return false unless regex == other.regex
return false unless string == other.string

return @ovector.memcmp(other.@ovector, (size + 1) * 2) == 0
return @ovector.memcmp(other.@ovector, size * 2) == 0
end

private def check_index_out_of_bounds(index)
raise_invalid_group_index(index) unless valid_group?(index)
end

private def valid_group?(index)
index <= @size
index < size
end

private def raise_invalid_group_index(index)
Expand Down

0 comments on commit 9bc5302

Please sign in to comment.