summaryrefslogtreecommitdiff
path: root/spec/ruby/core/matchdata
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/matchdata')
-rw-r--r--spec/ruby/core/matchdata/begin_spec.rb30
-rw-r--r--spec/ruby/core/matchdata/captures_spec.rb7
-rw-r--r--spec/ruby/core/matchdata/element_reference_spec.rb87
-rw-r--r--spec/ruby/core/matchdata/end_spec.rb30
-rw-r--r--spec/ruby/core/matchdata/eql_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/equal_value_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/hash_spec.rb5
-rw-r--r--spec/ruby/core/matchdata/inspect_spec.rb17
-rw-r--r--spec/ruby/core/matchdata/length_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/named_captures_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/names_spec.rb33
-rw-r--r--spec/ruby/core/matchdata/offset_spec.rb30
-rw-r--r--spec/ruby/core/matchdata/post_match_spec.rb36
-rw-r--r--spec/ruby/core/matchdata/pre_match_spec.rb36
-rw-r--r--spec/ruby/core/matchdata/regexp_spec.rb13
-rw-r--r--spec/ruby/core/matchdata/shared/eql.rb26
-rw-r--r--spec/ruby/core/matchdata/shared/length.rb5
-rw-r--r--spec/ruby/core/matchdata/size_spec.rb6
-rw-r--r--spec/ruby/core/matchdata/string_spec.rb14
-rw-r--r--spec/ruby/core/matchdata/to_a_spec.rb7
-rw-r--r--spec/ruby/core/matchdata/to_s_spec.rb7
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb23
22 files changed, 443 insertions, 0 deletions
diff --git a/spec/ruby/core/matchdata/begin_spec.rb b/spec/ruby/core/matchdata/begin_spec.rb
new file mode 100644
index 0000000000..b3d042066d
--- /dev/null
+++ b/spec/ruby/core/matchdata/begin_spec.rb
@@ -0,0 +1,30 @@
+# -*- encoding: utf-8 -*-
+
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#begin" do
+ it "returns the offset of the start of the nth element" do
+ match_data = /(.)(.)(\d+)(\d)/.match("THX1138.")
+ match_data.begin(0).should == 1
+ match_data.begin(2).should == 2
+ end
+
+ it "returns nil when the nth match isn't found" do
+ match_data = /something is( not)? (right)/.match("something is right")
+ match_data.begin(1).should be_nil
+ end
+
+ it "returns the offset for multi byte strings" do
+ match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.")
+ match_data.begin(0).should == 1
+ match_data.begin(2).should == 2
+ end
+
+ not_supported_on :opal do
+ it "returns the offset for multi byte strings with unicode regexp" do
+ match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.")
+ match_data.begin(0).should == 1
+ match_data.begin(2).should == 2
+ end
+ end
+end
diff --git a/spec/ruby/core/matchdata/captures_spec.rb b/spec/ruby/core/matchdata/captures_spec.rb
new file mode 100644
index 0000000000..2a83b26cd4
--- /dev/null
+++ b/spec/ruby/core/matchdata/captures_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#captures" do
+ it "returns an array of the match captures" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.").captures.should == ["H","X","113","8"]
+ end
+end
diff --git a/spec/ruby/core/matchdata/element_reference_spec.rb b/spec/ruby/core/matchdata/element_reference_spec.rb
new file mode 100644
index 0000000000..17d16a5526
--- /dev/null
+++ b/spec/ruby/core/matchdata/element_reference_spec.rb
@@ -0,0 +1,87 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#[]" do
+ it "acts as normal array indexing [index]" do
+ md = /(.)(.)(\d+)(\d)/.match("THX1138.")
+
+ md[0].should == 'HX1138'
+ md[1].should == 'H'
+ md[2].should == 'X'
+ md[-3].should == 'X'
+ md[10000].should == nil
+ md[-10000].should == nil
+ end
+
+ it "supports accessors [start, length]" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.")[1, 2].should == %w|H X|
+ /(.)(.)(\d+)(\d)/.match("THX1138.")[-3, 2].should == %w|X 113|
+ end
+
+ it "supports ranges [start..end]" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.")[1..3].should == %w|H X 113|
+ end
+end
+
+describe "MatchData#[Symbol]" do
+ it "returns the corresponding named match when given a Symbol" do
+ md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+ md[:a].should == 'ack'
+ md[:t].should == 'tack'
+ end
+
+ it "returns the corresponding named match when given a String" do
+ md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+ md['a'].should == 'ack'
+ md['t'].should == 'tack'
+ end
+
+ it "returns the matching version of multiple corresponding named match" do
+ regexp = /(?:
+ A(?<word>\w+)
+ |
+ B(?<word>\w+)
+ )/x
+ md_a = regexp.match("Afoo")
+ md_b = regexp.match("Bfoo")
+
+ md_a[:word].should == "foo"
+ md_b[:word].should == "foo"
+
+ md_a['word'].should == "foo"
+ md_b['word'].should == "foo"
+ end
+
+ it "returns the last match when multiple named matches exist with the same name" do
+ md = /(?<word>hay)(?<word>stack)/.match('haystack')
+ md[:word].should == "stack"
+ md['word'].should == "stack"
+ end
+
+ it "returns nil on non-matching named matches" do
+ regexp = /(?<foo>foo )?(?<bar>bar)/
+ full_match = regexp.match("foo bar")
+ partial_match = regexp.match("bar")
+
+ full_match[:foo].should == "foo "
+ partial_match[:foo].should == nil
+
+ full_match['foo'].should == "foo "
+ partial_match['foo'].should == nil
+ end
+
+ it "raises an IndexError if there is no named match corresponding to the Symbol" do
+ md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+ lambda { md[:baz] }.should raise_error(IndexError, /baz/)
+ end
+
+ it "raises an IndexError if there is no named match corresponding to the String" do
+ md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+ lambda { md['baz'] }.should raise_error(IndexError, /baz/)
+ end
+
+ it "returns matches in the String's encoding" do
+ rex = /(?<t>t(?<a>ack))/u
+ md = 'haystack'.force_encoding('euc-jp').match(rex)
+ md[:t].encoding.should == Encoding::EUC_JP
+ end
+end
diff --git a/spec/ruby/core/matchdata/end_spec.rb b/spec/ruby/core/matchdata/end_spec.rb
new file mode 100644
index 0000000000..4e74492105
--- /dev/null
+++ b/spec/ruby/core/matchdata/end_spec.rb
@@ -0,0 +1,30 @@
+# -*- encoding: utf-8 -*-
+
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#end" do
+ it "returns the offset of the end of the nth element" do
+ match_data = /(.)(.)(\d+)(\d)/.match("THX1138.")
+ match_data.end(0).should == 7
+ match_data.end(2).should == 3
+ end
+
+ it "returns nil when the nth match isn't found" do
+ match_data = /something is( not)? (right)/.match("something is right")
+ match_data.end(1).should be_nil
+ end
+
+ it "returns the offset for multi byte strings" do
+ match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.")
+ match_data.end(0).should == 7
+ match_data.end(2).should == 3
+ end
+
+ not_supported_on :opal do
+ it "returns the offset for multi byte strings with unicode regexp" do
+ match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.")
+ match_data.end(0).should == 7
+ match_data.end(2).should == 3
+ end
+ end
+end
diff --git a/spec/ruby/core/matchdata/eql_spec.rb b/spec/ruby/core/matchdata/eql_spec.rb
new file mode 100644
index 0000000000..192acbcd13
--- /dev/null
+++ b/spec/ruby/core/matchdata/eql_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/eql', __FILE__)
+
+describe "MatchData#eql?" do
+ it_behaves_like(:matchdata_eql, :eql?)
+end
diff --git a/spec/ruby/core/matchdata/equal_value_spec.rb b/spec/ruby/core/matchdata/equal_value_spec.rb
new file mode 100644
index 0000000000..0d33d0acf2
--- /dev/null
+++ b/spec/ruby/core/matchdata/equal_value_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/eql', __FILE__)
+
+describe "MatchData#==" do
+ it_behaves_like(:matchdata_eql, :==)
+end
diff --git a/spec/ruby/core/matchdata/hash_spec.rb b/spec/ruby/core/matchdata/hash_spec.rb
new file mode 100644
index 0000000000..1d5c8a203f
--- /dev/null
+++ b/spec/ruby/core/matchdata/hash_spec.rb
@@ -0,0 +1,5 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#hash" do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/core/matchdata/inspect_spec.rb b/spec/ruby/core/matchdata/inspect_spec.rb
new file mode 100644
index 0000000000..3cf968b6f5
--- /dev/null
+++ b/spec/ruby/core/matchdata/inspect_spec.rb
@@ -0,0 +1,17 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#inspect" do
+ before :each do
+ @match_data = /(.)(.)(\d+)(\d)/.match("THX1138.")
+ end
+
+ it "returns a String" do
+ @match_data.inspect.should be_kind_of(String)
+ end
+
+ it "returns a human readable representation that contains entire matched string and the captures" do
+ # yeah, hardcoding the inspect output is not ideal, but in this case
+ # it makes perfect sense. See JRUBY-4558 for example.
+ @match_data.inspect.should == '#<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">'
+ end
+end
diff --git a/spec/ruby/core/matchdata/length_spec.rb b/spec/ruby/core/matchdata/length_spec.rb
new file mode 100644
index 0000000000..75cf607598
--- /dev/null
+++ b/spec/ruby/core/matchdata/length_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/length', __FILE__)
+
+describe "MatchData#length" do
+ it_behaves_like(:matchdata_length, :length)
+end
diff --git a/spec/ruby/core/matchdata/named_captures_spec.rb b/spec/ruby/core/matchdata/named_captures_spec.rb
new file mode 100644
index 0000000000..cc3aaa2b45
--- /dev/null
+++ b/spec/ruby/core/matchdata/named_captures_spec.rb
@@ -0,0 +1,13 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+ruby_version_is '2.4' do
+ describe 'MatchData#named_captures' do
+ it 'returns a Hash that has captured name and the matched string pairs' do
+ /(?<a>.)(?<b>.)?/.match('0').named_captures.should == { 'a' => '0', 'b' => nil }
+ end
+
+ it 'prefers later captures' do
+ /\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)\z/.match('0123').named_captures.should == { 'a' => '3', 'b' => '2' }
+ end
+ end
+end
diff --git a/spec/ruby/core/matchdata/names_spec.rb b/spec/ruby/core/matchdata/names_spec.rb
new file mode 100644
index 0000000000..e298c85593
--- /dev/null
+++ b/spec/ruby/core/matchdata/names_spec.rb
@@ -0,0 +1,33 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#names" do
+ it "returns an Array" do
+ md = 'haystack'.match(/(?<yellow>hay)/)
+ md.names.should be_an_instance_of(Array)
+ end
+
+ it "sets each element to a String" do
+ 'haystack'.match(/(?<yellow>hay)/).names.all? do |e|
+ e.should be_an_instance_of(String)
+ end
+ end
+
+ it "returns the names of the named capture groups" do
+ md = 'haystack'.match(/(?<yellow>hay).(?<pin>tack)/)
+ md.names.should == ['yellow', 'pin']
+ end
+
+ it "returns [] if there were no named captures" do
+ 'haystack'.match(/(hay).(tack)/).names.should == []
+ end
+
+ it "returns each name only once" do
+ md = 'haystack'.match(/(?<hay>hay)(?<dot>.)(?<hay>tack)/)
+ md.names.should == ['hay', 'dot']
+ end
+
+ it "equals Regexp#names" do
+ r = /(?<hay>hay)(?<dot>.)(?<hay>tack)/
+ 'haystack'.match(r).names.should == r.names
+ end
+end
diff --git a/spec/ruby/core/matchdata/offset_spec.rb b/spec/ruby/core/matchdata/offset_spec.rb
new file mode 100644
index 0000000000..6ddb56c1a7
--- /dev/null
+++ b/spec/ruby/core/matchdata/offset_spec.rb
@@ -0,0 +1,30 @@
+# -*- encoding: utf-8 -*-
+
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#offset" do
+ it "returns a two element array with the begin and end of the nth match" do
+ match_data = /(.)(.)(\d+)(\d)/.match("THX1138.")
+ match_data.offset(0).should == [1, 7]
+ match_data.offset(4).should == [6, 7]
+ end
+
+ it "returns [nil, nil] when the nth match isn't found" do
+ match_data = /something is( not)? (right)/.match("something is right")
+ match_data.offset(1).should == [nil, nil]
+ end
+
+ it "returns the offset for multi byte strings" do
+ match_data = /(.)(.)(\d+)(\d)/.match("TñX1138.")
+ match_data.offset(0).should == [1, 7]
+ match_data.offset(4).should == [6, 7]
+ end
+
+ not_supported_on :opal do
+ it "returns the offset for multi byte strings with unicode regexp" do
+ match_data = /(.)(.)(\d+)(\d)/u.match("TñX1138.")
+ match_data.offset(0).should == [1, 7]
+ match_data.offset(4).should == [6, 7]
+ end
+ end
+end
diff --git a/spec/ruby/core/matchdata/post_match_spec.rb b/spec/ruby/core/matchdata/post_match_spec.rb
new file mode 100644
index 0000000000..670e0887ab
--- /dev/null
+++ b/spec/ruby/core/matchdata/post_match_spec.rb
@@ -0,0 +1,36 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#post_match" do
+ it "returns the string after the match equiv. special var $'" do
+ /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").post_match.should == ': The Movie'
+ $'.should == ': The Movie'
+ end
+
+ it "keeps taint status from the source string" do
+ str = "THX1138: The Movie"
+ str.taint
+ res = /(.)(.)(\d+)(\d)/.match(str).post_match
+ res.tainted?.should be_true
+ $'.tainted?.should be_true
+ end
+
+ it "keeps untrusted status from the source string" do
+ str = "THX1138: The Movie"
+ str.untrust
+ res = /(.)(.)(\d+)(\d)/.match(str).post_match
+ res.untrusted?.should be_true
+ $'.untrusted?.should be_true
+ end
+
+ with_feature :encoding do
+ it "sets the encoding to the encoding of the source String" do
+ str = "abc".force_encoding Encoding::EUC_JP
+ str.match(/b/).post_match.encoding.should equal(Encoding::EUC_JP)
+ end
+
+ it "sets an empty result to the encoding of the source String" do
+ str = "abc".force_encoding Encoding::ISO_8859_1
+ str.match(/c/).post_match.encoding.should equal(Encoding::ISO_8859_1)
+ end
+ end
+end
diff --git a/spec/ruby/core/matchdata/pre_match_spec.rb b/spec/ruby/core/matchdata/pre_match_spec.rb
new file mode 100644
index 0000000000..1f1f9daec6
--- /dev/null
+++ b/spec/ruby/core/matchdata/pre_match_spec.rb
@@ -0,0 +1,36 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#pre_match" do
+ it "returns the string before the match, equiv. special var $`" do
+ /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").pre_match.should == 'T'
+ $`.should == 'T'
+ end
+
+ it "keeps taint status from the source string" do
+ str = "THX1138: The Movie"
+ str.taint
+ res = /(.)(.)(\d+)(\d)/.match(str).pre_match
+ res.tainted?.should be_true
+ $`.tainted?.should be_true
+ end
+
+ it "keeps untrusted status from the source string" do
+ str = "THX1138: The Movie"
+ str.untrust
+ res = /(.)(.)(\d+)(\d)/.match(str).pre_match
+ res.untrusted?.should be_true
+ $`.untrusted?.should be_true
+ end
+
+ with_feature :encoding do
+ it "sets the encoding to the encoding of the source String" do
+ str = "abc".force_encoding Encoding::EUC_JP
+ str.match(/b/).pre_match.encoding.should equal(Encoding::EUC_JP)
+ end
+
+ it "sets an empty result to the encoding of the source String" do
+ str = "abc".force_encoding Encoding::ISO_8859_1
+ str.match(/a/).pre_match.encoding.should equal(Encoding::ISO_8859_1)
+ end
+ end
+end
diff --git a/spec/ruby/core/matchdata/regexp_spec.rb b/spec/ruby/core/matchdata/regexp_spec.rb
new file mode 100644
index 0000000000..2fdca34c30
--- /dev/null
+++ b/spec/ruby/core/matchdata/regexp_spec.rb
@@ -0,0 +1,13 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#regexp" do
+ it "returns a Regexp object" do
+ m = 'haystack'.match(/hay/)
+ m.regexp.should be_an_instance_of(Regexp)
+ end
+
+ it "returns the pattern used in the match" do
+ m = 'haystack'.match(/hay/)
+ m.regexp.should == /hay/
+ end
+end
diff --git a/spec/ruby/core/matchdata/shared/eql.rb b/spec/ruby/core/matchdata/shared/eql.rb
new file mode 100644
index 0000000000..098d82db5b
--- /dev/null
+++ b/spec/ruby/core/matchdata/shared/eql.rb
@@ -0,0 +1,26 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+
+describe :matchdata_eql, shared: true do
+ it "returns true if both operands have equal target strings, patterns, and match positions" do
+ a = 'haystack'.match(/hay/)
+ b = 'haystack'.match(/hay/)
+ a.send(@method, b).should be_true
+ end
+
+ it "returns false if the operands have different target strings" do
+ a = 'hay'.match(/hay/)
+ b = 'haystack'.match(/hay/)
+ a.send(@method, b).should be_false
+ end
+
+ it "returns false if the operands have different patterns" do
+ a = 'haystack'.match(/h.y/)
+ b = 'haystack'.match(/hay/)
+ a.send(@method, b).should be_false
+ end
+
+ it "returns false if the argument is not a MatchData object" do
+ a = 'haystack'.match(/hay/)
+ a.send(@method, Object.new).should be_false
+ end
+end
diff --git a/spec/ruby/core/matchdata/shared/length.rb b/spec/ruby/core/matchdata/shared/length.rb
new file mode 100644
index 0000000000..6312a7ed4c
--- /dev/null
+++ b/spec/ruby/core/matchdata/shared/length.rb
@@ -0,0 +1,5 @@
+describe :matchdata_length, shared: true do
+ it "length should return the number of elements in the match array" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.").send(@method).should == 5
+ end
+end
diff --git a/spec/ruby/core/matchdata/size_spec.rb b/spec/ruby/core/matchdata/size_spec.rb
new file mode 100644
index 0000000000..e043f51870
--- /dev/null
+++ b/spec/ruby/core/matchdata/size_spec.rb
@@ -0,0 +1,6 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/length', __FILE__)
+
+describe "MatchData#size" do
+ it_behaves_like(:matchdata_length, :size)
+end
diff --git a/spec/ruby/core/matchdata/string_spec.rb b/spec/ruby/core/matchdata/string_spec.rb
new file mode 100644
index 0000000000..793684d36a
--- /dev/null
+++ b/spec/ruby/core/matchdata/string_spec.rb
@@ -0,0 +1,14 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#string" do
+ it "returns a copy of the match string" do
+ str = /(.)(.)(\d+)(\d)/.match("THX1138.").string
+ str.should == "THX1138."
+ end
+
+ it "returns a frozen copy of the match string" do
+ str = /(.)(.)(\d+)(\d)/.match("THX1138.").string
+ str.should == "THX1138."
+ str.frozen?.should == true
+ end
+end
diff --git a/spec/ruby/core/matchdata/to_a_spec.rb b/spec/ruby/core/matchdata/to_a_spec.rb
new file mode 100644
index 0000000000..592a68db0e
--- /dev/null
+++ b/spec/ruby/core/matchdata/to_a_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#to_a" do
+ it "returns an array of matches" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.").to_a.should == ["HX1138", "H", "X", "113", "8"]
+ end
+end
diff --git a/spec/ruby/core/matchdata/to_s_spec.rb b/spec/ruby/core/matchdata/to_s_spec.rb
new file mode 100644
index 0000000000..3eb3b92533
--- /dev/null
+++ b/spec/ruby/core/matchdata/to_s_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#to_s" do
+ it "returns the entire matched string" do
+ /(.)(.)(\d+)(\d)/.match("THX1138.").to_s.should == "HX1138"
+ end
+end
diff --git a/spec/ruby/core/matchdata/values_at_spec.rb b/spec/ruby/core/matchdata/values_at_spec.rb
new file mode 100644
index 0000000000..0b2727e001
--- /dev/null
+++ b/spec/ruby/core/matchdata/values_at_spec.rb
@@ -0,0 +1,23 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "MatchData#values_at" do
+ it "returns an array of the matching value" do
+ /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0, 2, -2).should == ["HX1138", "X", "113"]
+ end
+
+ describe "when passed a Range" do
+ it "returns an array of the matching value" do
+ /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(2..4, 0..1).should == ["X", "113", "8", "HX1138", "H"]
+ end
+ end
+
+ ruby_version_is '2.4' do
+ it 'slices captures with the given names' do
+ /(?<a>.)(?<b>.)(?<c>.)/.match('012').values_at(:c, :a).should == ['2', '0']
+ end
+
+ it 'takes names and indices' do
+ /\A(?<a>.)(?<b>.)\z/.match('01').values_at(0, 1, 2, :a, :b).should == ['01', '0', '1', '0', '1']
+ end
+ end
+end