nokogiri 1.5.2-java → 1.5.3-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- data/CHANGELOG.ja.rdoc +35 -0
- data/CHANGELOG.rdoc +37 -2
- data/Manifest.txt +11 -3
- data/README.rdoc +1 -1
- data/ROADMAP.md +86 -0
- data/{nokogiri_help_responses.md → STANDARD_RESPONSES.md} +11 -4
- data/Y_U_NO_GEMSPEC.md +155 -0
- data/build_all +58 -0
- data/ext/java/nokogiri/HtmlDocument.java +10 -1
- data/ext/java/nokogiri/XmlAttr.java +11 -1
- data/ext/java/nokogiri/XmlDocument.java +4 -0
- data/ext/java/nokogiri/XmlNamespace.java +25 -0
- data/ext/java/nokogiri/XmlNode.java +6 -6
- data/ext/java/nokogiri/XmlReader.java +19 -4
- data/ext/java/nokogiri/XmlSaxPushParser.java +88 -57
- data/ext/java/nokogiri/XmlSyntaxError.java +15 -3
- data/ext/java/nokogiri/XmlXpathContext.java +3 -3
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +2 -1
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +89 -1
- data/ext/java/nokogiri/internals/ParserContext.java +23 -2
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +18 -1
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +2 -3
- data/ext/nokogiri/extconf.rb +1 -1
- data/ext/nokogiri/xml_io.c +1 -1
- data/ext/nokogiri/xml_namespace.c +0 -6
- data/ext/nokogiri/xml_node.c +11 -11
- data/ext/nokogiri/xml_node_set.c +1 -1
- data/ext/nokogiri/xml_xpath_context.c +20 -16
- data/ext/nokogiri/xml_xpath_context.h +1 -0
- data/ext/nokogiri/xslt_stylesheet.c +7 -64
- data/lib/nokogiri/css/node.rb +3 -0
- data/lib/nokogiri/css/parser.rb +244 -203
- data/lib/nokogiri/css/parser.y +20 -2
- data/lib/nokogiri/css/xpath_visitor.rb +2 -2
- data/lib/nokogiri/html/document.rb +2 -1
- data/lib/nokogiri/html/element_description_defaults.rb +1 -1
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml/document.rb +1 -1
- data/lib/nokogiri/xml/parse_options.rb +2 -2
- data/lib/nokogiri/xml/sax/document.rb +1 -1
- data/lib/nokogiri/xml/sax/parser.rb +1 -1
- data/lib/nokogiri/xslt.rb +1 -1
- data/test/css/test_parser.rb +38 -0
- data/test/files/to_be_xincluded.xml +2 -0
- data/test/files/xinclude.xml +4 -0
- data/test/helper.rb +18 -45
- data/test/html/sax/test_parser.rb +5 -3
- data/test/html/sax/test_parser_context.rb +8 -10
- data/test/html/test_document.rb +19 -5
- data/test/html/test_node.rb +2 -4
- data/test/test_reader.rb +63 -0
- data/test/test_xslt_transforms.rb +3 -1
- data/test/xml/sax/test_parser_context.rb +10 -17
- data/test/xml/sax/test_push_parser.rb +1 -0
- data/test/xml/test_attr.rb +5 -6
- data/test/xml/test_builder.rb +5 -6
- data/test/xml/test_cdata.rb +1 -3
- data/test/xml/test_document.rb +11 -14
- data/test/xml/test_document_encoding.rb +3 -1
- data/test/xml/test_document_fragment.rb +27 -8
- data/test/xml/test_node.rb +21 -0
- data/test/xml/test_node_set.rb +2 -2
- data/test/xml/test_text.rb +1 -3
- data/test/xml/test_unparented_node.rb +2 -2
- data/test/xml/test_xpath.rb +15 -6
- data/test/xslt/test_custom_functions.rb +35 -0
- data/test_all +84 -0
- metadata +13 -8
- data/ext/java/nokogiri/internals/PushInputStream.java +0 -411
@@ -158,7 +158,9 @@ encoding="iso-8859-1" indent="yes"/>
|
|
158
158
|
assert_equal result_array, result_hash
|
159
159
|
end
|
160
160
|
|
161
|
-
if Nokogiri.uses_libxml?
|
161
|
+
if Nokogiri.uses_libxml?
|
162
|
+
# By now, cannot get it working on JRuby, see:
|
163
|
+
# http://yokolet.blogspot.com/2010/10/pure-java-nokogiri-xslt-extension.html
|
162
164
|
def test_exslt
|
163
165
|
assert doc = Nokogiri::XML.parse(File.read(EXML_FILE))
|
164
166
|
assert doc.xml?
|
@@ -66,15 +66,12 @@ world
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def test_from_io
|
69
|
-
|
70
|
-
|
71
|
-
end
|
69
|
+
ctx = ParserContext.new StringIO.new('fo'), 'UTF-8'
|
70
|
+
assert ctx
|
72
71
|
end
|
73
72
|
|
74
73
|
def test_from_string
|
75
|
-
|
76
|
-
ParserContext.new 'blah blah'
|
77
|
-
end
|
74
|
+
assert ParserContext.new 'blah blah'
|
78
75
|
end
|
79
76
|
|
80
77
|
def test_parse_with
|
@@ -85,20 +82,16 @@ world
|
|
85
82
|
end
|
86
83
|
|
87
84
|
def test_parse_with_sax_parser
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
ctx.parse_with parser
|
93
|
-
end
|
85
|
+
xml = "<root />"
|
86
|
+
ctx = ParserContext.new xml
|
87
|
+
parser = Parser.new Doc.new
|
88
|
+
assert_nil ctx.parse_with parser
|
94
89
|
end
|
95
90
|
|
96
91
|
def test_from_file
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
ctx.parse_with parser
|
101
|
-
end
|
92
|
+
ctx = ParserContext.file XML_FILE
|
93
|
+
parser = Parser.new Doc.new
|
94
|
+
assert_nil ctx.parse_with parser
|
102
95
|
end
|
103
96
|
|
104
97
|
def test_parse_with_returns_nil
|
@@ -142,6 +142,7 @@ module Nokogiri
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def test_broken_encoding
|
145
|
+
skip("ultra hard to fix for pure Java version") if Nokogiri.jruby?
|
145
146
|
@parser.options |= XML::ParseOptions::RECOVER
|
146
147
|
# This is ISO_8859-1:
|
147
148
|
@parser.<< "<?xml version='1.0' encoding='UTF-8'?><r>Gau\337</r>"
|
data/test/xml/test_attr.rb
CHANGED
@@ -4,12 +4,11 @@ module Nokogiri
|
|
4
4
|
module XML
|
5
5
|
class TestAttr < Nokogiri::TestCase
|
6
6
|
def test_new
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
7
|
+
100.times {
|
8
|
+
doc = Nokogiri::XML::Document.new
|
9
|
+
assert doc
|
10
|
+
assert Nokogiri::XML::Attr.new(doc, 'foo')
|
11
|
+
}
|
13
12
|
end
|
14
13
|
|
15
14
|
def test_content=
|
data/test/xml/test_builder.rb
CHANGED
@@ -47,14 +47,13 @@ module Nokogiri
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def test_builder_with_unlink
|
50
|
-
|
51
|
-
|
52
|
-
xml.
|
53
|
-
|
54
|
-
xml.bar2
|
55
|
-
end
|
50
|
+
b = Nokogiri::XML::Builder.new do |xml|
|
51
|
+
xml.foo do
|
52
|
+
xml.bar { xml.parent.unlink }
|
53
|
+
xml.bar2
|
56
54
|
end
|
57
55
|
end
|
56
|
+
assert b
|
58
57
|
end
|
59
58
|
|
60
59
|
def test_with_root
|
data/test/xml/test_cdata.rb
CHANGED
data/test/xml/test_document.rb
CHANGED
@@ -124,9 +124,8 @@ module Nokogiri
|
|
124
124
|
|
125
125
|
def test_pp
|
126
126
|
out = StringIO.new('')
|
127
|
-
|
128
|
-
|
129
|
-
end
|
127
|
+
::PP.pp @xml, out
|
128
|
+
assert_operator out.string.length, :>, 0
|
130
129
|
end
|
131
130
|
|
132
131
|
def test_create_internal_subset_on_existing_subset
|
@@ -295,9 +294,7 @@ module Nokogiri
|
|
295
294
|
end
|
296
295
|
|
297
296
|
def test_parse_handles_nil_gracefully
|
298
|
-
|
299
|
-
@doc = Nokogiri::XML::Document.parse(nil)
|
300
|
-
end
|
297
|
+
@doc = Nokogiri::XML::Document.parse(nil)
|
301
298
|
assert_instance_of Nokogiri::XML::Document, @doc
|
302
299
|
end
|
303
300
|
|
@@ -358,13 +355,17 @@ module Nokogiri
|
|
358
355
|
def test_subclass_parse
|
359
356
|
klass = Class.new(Nokogiri::XML::Document)
|
360
357
|
doc = klass.parse(File.read(XML_FILE))
|
361
|
-
|
358
|
+
# lame hack uses root to avoid comparing DOCTYPE tags which can appear out of order.
|
359
|
+
# I should really finish lorax and use that here.
|
360
|
+
assert_equal @xml.root.to_s, doc.root.to_s
|
362
361
|
assert_instance_of klass, doc
|
363
362
|
end
|
364
363
|
|
365
364
|
def test_document_parse_method
|
366
365
|
xml = Nokogiri::XML::Document.parse(File.read(XML_FILE))
|
367
|
-
|
366
|
+
# lame hack uses root to avoid comparing DOCTYPE tags which can appear out of order.
|
367
|
+
# I should really finish lorax and use that here.
|
368
|
+
assert_equal @xml.root.to_s, xml.root.to_s
|
368
369
|
end
|
369
370
|
|
370
371
|
def test_encoding=
|
@@ -629,9 +630,7 @@ module Nokogiri
|
|
629
630
|
|
630
631
|
def test_new
|
631
632
|
doc = nil
|
632
|
-
|
633
|
-
doc = Nokogiri::XML::Document.new
|
634
|
-
}
|
633
|
+
doc = Nokogiri::XML::Document.new
|
635
634
|
assert doc
|
636
635
|
assert doc.xml?
|
637
636
|
assert_nil doc.root
|
@@ -639,9 +638,7 @@ module Nokogiri
|
|
639
638
|
|
640
639
|
def test_set_root
|
641
640
|
doc = nil
|
642
|
-
|
643
|
-
doc = Nokogiri::XML::Document.new
|
644
|
-
}
|
641
|
+
doc = Nokogiri::XML::Document.new
|
645
642
|
assert doc
|
646
643
|
assert doc.xml?
|
647
644
|
assert_nil doc.root
|
@@ -176,15 +176,34 @@ module Nokogiri
|
|
176
176
|
assert fragment.children.respond_to?(:awesome!), fragment.children.class
|
177
177
|
end
|
178
178
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
179
|
+
if Nokogiri.uses_libxml?
|
180
|
+
def test_for_libxml_in_context_fragment_parsing_bug_workaround
|
181
|
+
10.times do
|
182
|
+
begin
|
183
|
+
fragment = Nokogiri::XML.fragment("<div></div>")
|
184
|
+
parent = fragment.children.first
|
185
|
+
child = parent.parse("<h1></h1>").first
|
186
|
+
parent.add_child child
|
187
|
+
end
|
188
|
+
GC.start
|
186
189
|
end
|
187
|
-
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_for_libxml_in_context_memory_badness_when_encountering_encoding_errors
|
193
|
+
# see issue #643 for background
|
194
|
+
# this test exists solely to raise an error during valgrind test runs.
|
195
|
+
html = <<-EOHTML
|
196
|
+
<html>
|
197
|
+
<head>
|
198
|
+
<meta http-equiv="Content-Type" content="text/html; charset=shizzle" />
|
199
|
+
</head>
|
200
|
+
<body>
|
201
|
+
<div>Foo</div>
|
202
|
+
</body>
|
203
|
+
</html>
|
204
|
+
EOHTML
|
205
|
+
doc = Nokogiri::HTML html
|
206
|
+
doc.at_css("div").replace("Bar")
|
188
207
|
end
|
189
208
|
end
|
190
209
|
end
|
data/test/xml/test_node.rb
CHANGED
@@ -993,6 +993,27 @@ EOXML
|
|
993
993
|
assert_no_match("<ul>\n <li>", xml.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
|
994
994
|
assert_no_match("<ul>\n <li>", node.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
|
995
995
|
end
|
996
|
+
|
997
|
+
# issue 647
|
998
|
+
def test_default_namespace_should_be_created
|
999
|
+
subject = Nokogiri::XML.parse('<foo xml:bar="http://bar.com"/>').root
|
1000
|
+
ns = subject.attributes['bar'].namespace
|
1001
|
+
assert_not_nil ns
|
1002
|
+
assert_equal ns.class, Nokogiri::XML::Namespace
|
1003
|
+
assert_equal 'xml', ns.prefix
|
1004
|
+
assert_equal "http://www.w3.org/XML/1998/namespace", ns.href
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
# issue 648
|
1008
|
+
def test_namespace_without_prefix_should_be_set
|
1009
|
+
node = Nokogiri::XML.parse('<foo xmlns="http://bar.com"/>').root
|
1010
|
+
subject = Nokogiri::XML::Node.new 'foo', node.document
|
1011
|
+
subject.namespace = node.namespace
|
1012
|
+
ns = subject.namespace
|
1013
|
+
assert_equal ns.class, Nokogiri::XML::Namespace
|
1014
|
+
assert_nil ns.prefix
|
1015
|
+
assert_equal ns.href, "http://bar.com"
|
1016
|
+
end
|
996
1017
|
end
|
997
1018
|
end
|
998
1019
|
end
|
data/test/xml/test_node_set.rb
CHANGED
@@ -168,7 +168,7 @@ module Nokogiri
|
|
168
168
|
set = html.xpath("/html/body/div")
|
169
169
|
assert_equal set.first, set.search(".a").first
|
170
170
|
end
|
171
|
-
|
171
|
+
|
172
172
|
def test_css_search_with_namespace
|
173
173
|
fragment = Nokogiri::XML.fragment(<<-eoxml)
|
174
174
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
@@ -176,7 +176,7 @@ module Nokogiri
|
|
176
176
|
<body></body>
|
177
177
|
</html>
|
178
178
|
eoxml
|
179
|
-
|
179
|
+
assert fragment.children.search( 'body', { 'xmlns' => 'http://www.w3.org/1999/xhtml' })
|
180
180
|
end
|
181
181
|
|
182
182
|
def test_double_equal
|
data/test/xml/test_text.rb
CHANGED
@@ -252,8 +252,8 @@ module Nokogiri
|
|
252
252
|
doc = Nokogiri::XML "<root>foo</root>"
|
253
253
|
pi = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", %q{type="text/xsl" href="foo.xsl"})
|
254
254
|
doc.root.add_previous_sibling pi
|
255
|
-
expected_doc = %Q{<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="foo.xsl"?>\n<root>foo</root
|
256
|
-
|
255
|
+
expected_doc = %Q{<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="foo.xsl"?>\n<root>foo</root>}
|
256
|
+
assert_includes doc.to_xml, expected_doc
|
257
257
|
end
|
258
258
|
|
259
259
|
def test_find_by_css_with_tilde_eql
|
data/test/xml/test_xpath.rb
CHANGED
@@ -100,12 +100,10 @@ module Nokogiri
|
|
100
100
|
|
101
101
|
def test_css_search_uses_custom_selectors
|
102
102
|
set = @xml.xpath('//employee')
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
@xml.xpath("//employee[nokogiri:thing(.)]", @ns, @handler)
|
108
|
-
end
|
103
|
+
if Nokogiri.uses_libxml?
|
104
|
+
@xml.css('employee:thing()', @handler)
|
105
|
+
else
|
106
|
+
@xml.xpath("//employee[nokogiri:thing(.)]", @ns, @handler)
|
109
107
|
end
|
110
108
|
assert_equal(set.length, @handler.things.length)
|
111
109
|
assert_equal(set.to_a, @handler.things.flatten)
|
@@ -254,6 +252,17 @@ module Nokogiri
|
|
254
252
|
end
|
255
253
|
assert_equal 123.456, value
|
256
254
|
end
|
255
|
+
|
256
|
+
def test_custom_xpath_with_bullshit_arguments
|
257
|
+
xml = %q{<foo> </foo>}
|
258
|
+
doc = Nokogiri::XML.parse(xml)
|
259
|
+
foo = doc.xpath('//foo[bool_function(bar/baz)]', Class.new {
|
260
|
+
def bool_function(value)
|
261
|
+
true
|
262
|
+
end
|
263
|
+
}.new)
|
264
|
+
assert_equal foo, doc.xpath("//foo")
|
265
|
+
end
|
257
266
|
end
|
258
267
|
end
|
259
268
|
end
|
@@ -58,6 +58,41 @@ EOXSL
|
|
58
58
|
assert_equal 'FOO', result.css('title').first.text
|
59
59
|
end
|
60
60
|
|
61
|
+
|
62
|
+
def test_function_arguments
|
63
|
+
skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml?
|
64
|
+
foo = Class.new do
|
65
|
+
include MiniTest::Assertions
|
66
|
+
|
67
|
+
def multiarg *args
|
68
|
+
assert_equal ["abc", "xyz"], args
|
69
|
+
args.first
|
70
|
+
end
|
71
|
+
|
72
|
+
def numericarg arg
|
73
|
+
assert_equal 42, arg
|
74
|
+
arg
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
xsl = Nokogiri.XSLT(<<-EOXSL, "http://e.org/functions" => foo)
|
79
|
+
<?xml version="1.0"?>
|
80
|
+
<xsl:stylesheet version="1.0"
|
81
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
82
|
+
xmlns:f="http://e.org/functions"
|
83
|
+
extension-element-prefixes="f">
|
84
|
+
|
85
|
+
<xsl:template match="text()">
|
86
|
+
<xsl:copy-of select="f:multiarg('abc', 'xyz')"/>
|
87
|
+
<xsl:copy-of select="f:numericarg(42)"/>
|
88
|
+
</xsl:template>
|
89
|
+
</xsl:stylesheet>
|
90
|
+
EOXSL
|
91
|
+
|
92
|
+
xsl.transform @xml
|
93
|
+
end
|
94
|
+
|
95
|
+
|
61
96
|
def test_function_XSLT
|
62
97
|
skip("Pure Java version doesn't support this feature.") if !Nokogiri.uses_libxml?
|
63
98
|
foo = Class.new do
|
data/test_all
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#! /usr/bin/env bash
|
2
|
+
#
|
3
|
+
# script to run tests on all relevant rubies, and valgrind on supported rubies.
|
4
|
+
# outputs tests to `test.log` and valgrind output to `valgrind.log`.
|
5
|
+
#
|
6
|
+
# requires `rvm` to be installed. sorry about that, multiruby dudes.
|
7
|
+
#
|
8
|
+
|
9
|
+
RUBIES="ruby-1.9.3 jruby-1.6.5 ree-1.8.7 ruby-1.9.2 ruby-1.8.7"
|
10
|
+
TEST_LOG=test.log
|
11
|
+
VALGRIND_LOG=valgrind.log
|
12
|
+
|
13
|
+
# Load RVM into a shell session *as a function*
|
14
|
+
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
|
15
|
+
source "$HOME/.rvm/scripts/rvm"
|
16
|
+
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
|
17
|
+
source "/usr/local/rvm/scripts/rvm"
|
18
|
+
else
|
19
|
+
echo "ERROR: An RVM installation was not found.\n"
|
20
|
+
fi
|
21
|
+
|
22
|
+
> $TEST_LOG
|
23
|
+
> $VALGRIND_LOG
|
24
|
+
set -o errexit
|
25
|
+
|
26
|
+
function rvm_use {
|
27
|
+
current_ruby=$1
|
28
|
+
rvm use "${1}@nokogiri" --create
|
29
|
+
}
|
30
|
+
|
31
|
+
function generate_parser_and_tokenizer {
|
32
|
+
old_ruby=$current_ruby
|
33
|
+
rvm_use ruby-1.8.7
|
34
|
+
bundle exec rake generate 2>&1 > /dev/null
|
35
|
+
rvm_use $old_ruby
|
36
|
+
}
|
37
|
+
|
38
|
+
function clean {
|
39
|
+
bundle exec rake clean clobber 2>&1 > /dev/null
|
40
|
+
}
|
41
|
+
|
42
|
+
function compile {
|
43
|
+
echo "** compiling ..."
|
44
|
+
generate_parser_and_tokenizer
|
45
|
+
bundle exec rake compile 2>&1 > /dev/null
|
46
|
+
}
|
47
|
+
|
48
|
+
for ruby in $RUBIES ; do
|
49
|
+
rvm_use ${ruby}
|
50
|
+
if gem list bundler | fgrep -v 1.1.rc 2>&1 > /dev/null ; then
|
51
|
+
gem install bundler --pre
|
52
|
+
fi
|
53
|
+
bundle install --quiet --local || bundle install
|
54
|
+
clean
|
55
|
+
done
|
56
|
+
|
57
|
+
for ruby in $RUBIES ; do
|
58
|
+
rvm_use ${ruby}
|
59
|
+
echo -e "**\n** testing nokogiri on ${ruby}\n**" | tee -a $TEST_LOG
|
60
|
+
clean
|
61
|
+
compile
|
62
|
+
echo "** running tests ..."
|
63
|
+
if [[ $ruby =~ "jruby" ]] ; then
|
64
|
+
# I get:
|
65
|
+
# /usr/lib/jvm/java-7-oracle/bin/java: symbol lookup error: /home/mike/.rvm/gems/jruby-1.6.5@nokogiri/gems/racc-1.4.7/lib/racc/cparse.so: undefined symbol: rb_catch
|
66
|
+
# if I use 'bundle exec' with jruby. Anybody?
|
67
|
+
rake test 2>&1 | tee -a $TEST_LOG
|
68
|
+
else
|
69
|
+
bundle exec rake test 2>&1 | tee -a $TEST_LOG
|
70
|
+
fi
|
71
|
+
clean
|
72
|
+
done
|
73
|
+
|
74
|
+
for ruby in $RUBIES ; do
|
75
|
+
if [[ ! $ruby =~ "jruby" ]] ; then
|
76
|
+
rvm_use ${ruby}
|
77
|
+
echo -e "**\n** nokogiri prerelease: ${ruby}\n**" | tee -a $VALGRIND_LOG
|
78
|
+
clean
|
79
|
+
compile
|
80
|
+
echo "** running valgrind on tests ..."
|
81
|
+
bundle exec rake test:valgrind 2>&1 | tee -a $VALGRIND_LOG
|
82
|
+
clean
|
83
|
+
fi
|
84
|
+
done
|