mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/csv.rb: Fixes #161 on github
* lib/csv.rb: You can now specify a pattern for :skip_lines. Matching lines will not be passed to the CSV parser. * lib/csv.rb: Patch by Christian Schwartz. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36743 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6ac1d39ace
commit
3c3e659196
3 changed files with 66 additions and 3 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,7 +1,14 @@
|
||||||
|
Tue Aug 21 05:43:00 2012 James Edward Gray II <james@graysoftinc.com>
|
||||||
|
|
||||||
|
* lib/csv.rb: Fixes #161 on github
|
||||||
|
* lib/csv.rb: You can now specify a pattern for :skip_lines.
|
||||||
|
Matching lines will not be passed to the CSV parser.
|
||||||
|
* lib/csv.rb: Patch by Christian Schwartz.
|
||||||
|
|
||||||
Tue Aug 21 05:25:41 2012 Eric Hodel <drbrain@segment7.net>
|
Tue Aug 21 05:25:41 2012 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
* re.c (rb_reg_initialize_m): Forgot to update output for or'd-options
|
* re.c (rb_reg_initialize_m): Forgot to update output for or'd-options
|
||||||
example.
|
example.
|
||||||
|
|
||||||
Tue Aug 21 05:18:03 2012 Eric Hodel <drbrain@segment7.net>
|
Tue Aug 21 05:18:03 2012 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
|
|
25
lib/csv.rb
25
lib/csv.rb
|
@ -973,6 +973,7 @@ class CSV
|
||||||
# <b><tt>:header_converters</tt></b>:: +nil+
|
# <b><tt>:header_converters</tt></b>:: +nil+
|
||||||
# <b><tt>:skip_blanks</tt></b>:: +false+
|
# <b><tt>:skip_blanks</tt></b>:: +false+
|
||||||
# <b><tt>:force_quotes</tt></b>:: +false+
|
# <b><tt>:force_quotes</tt></b>:: +false+
|
||||||
|
# <b><tt>:skip_lines</tt></b>:: +nil+
|
||||||
#
|
#
|
||||||
DEFAULT_OPTIONS = { col_sep: ",",
|
DEFAULT_OPTIONS = { col_sep: ",",
|
||||||
row_sep: :auto,
|
row_sep: :auto,
|
||||||
|
@ -984,7 +985,8 @@ class CSV
|
||||||
return_headers: false,
|
return_headers: false,
|
||||||
header_converters: nil,
|
header_converters: nil,
|
||||||
skip_blanks: false,
|
skip_blanks: false,
|
||||||
force_quotes: false }.freeze
|
force_quotes: false,
|
||||||
|
skip_lines: nil }.freeze
|
||||||
|
|
||||||
#
|
#
|
||||||
# This method will return a CSV instance, just like CSV::new(), but the
|
# This method will return a CSV instance, just like CSV::new(), but the
|
||||||
|
@ -1554,6 +1556,14 @@ class CSV
|
||||||
# skip over any rows with no content.
|
# skip over any rows with no content.
|
||||||
# <b><tt>:force_quotes</tt></b>:: When set to a +true+ value, CSV will
|
# <b><tt>:force_quotes</tt></b>:: When set to a +true+ value, CSV will
|
||||||
# quote all CSV fields it creates.
|
# quote all CSV fields it creates.
|
||||||
|
# <b><tt>:skip_lines</tt></b>:: When set to an object responding to
|
||||||
|
# <tt>match</tt>, every line matching
|
||||||
|
# it is considered a comment and ignored
|
||||||
|
# during parsing. When set to +nil+
|
||||||
|
# no line is considered a comment.
|
||||||
|
# If the passed object does not respond
|
||||||
|
# to <tt>match</tt>, <tt>ArgumentError</tt>
|
||||||
|
# is thrown.
|
||||||
#
|
#
|
||||||
# See CSV::DEFAULT_OPTIONS for the default settings.
|
# See CSV::DEFAULT_OPTIONS for the default settings.
|
||||||
#
|
#
|
||||||
|
@ -1591,6 +1601,7 @@ class CSV
|
||||||
init_parsers(options)
|
init_parsers(options)
|
||||||
init_converters(options)
|
init_converters(options)
|
||||||
init_headers(options)
|
init_headers(options)
|
||||||
|
init_comments(options)
|
||||||
|
|
||||||
options.delete(:encoding)
|
options.delete(:encoding)
|
||||||
options.delete(:internal_encoding)
|
options.delete(:internal_encoding)
|
||||||
|
@ -1620,6 +1631,10 @@ class CSV
|
||||||
attr_reader :quote_char
|
attr_reader :quote_char
|
||||||
# The limit for field size, if any. See CSV::new for details.
|
# The limit for field size, if any. See CSV::new for details.
|
||||||
attr_reader :field_size_limit
|
attr_reader :field_size_limit
|
||||||
|
|
||||||
|
# The regex marking a line as a comment. See CSV::new for details
|
||||||
|
attr_reader :skip_lines
|
||||||
|
|
||||||
#
|
#
|
||||||
# Returns the current list of converters in effect. See CSV::new for details.
|
# Returns the current list of converters in effect. See CSV::new for details.
|
||||||
# Built-in converters will be returned by name, while others will be returned
|
# Built-in converters will be returned by name, while others will be returned
|
||||||
|
@ -1873,6 +1888,8 @@ class CSV
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
next if @skip_lines and @skip_lines.match parse
|
||||||
|
|
||||||
parts = parse.split(@col_sep, -1)
|
parts = parse.split(@col_sep, -1)
|
||||||
if parts.empty?
|
if parts.empty?
|
||||||
if in_extended_col
|
if in_extended_col
|
||||||
|
@ -2189,6 +2206,12 @@ class CSV
|
||||||
init_converters(options, :header_converters)
|
init_converters(options, :header_converters)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def init_comments(options)
|
||||||
|
@skip_lines = options.delete(:skip_lines)
|
||||||
|
if @skip_lines and not @skip_lines.respond_to?(:match)
|
||||||
|
raise ArgumentError, ":skip_lines has to respond to matches"
|
||||||
|
end
|
||||||
|
end
|
||||||
#
|
#
|
||||||
# The actual work method for adding converters, used by both CSV.convert() and
|
# The actual work method for adding converters, used by both CSV.convert() and
|
||||||
# CSV.header_convert().
|
# CSV.header_convert().
|
||||||
|
|
|
@ -274,4 +274,37 @@ class TestCSV::Features < TestCSV
|
||||||
assert(CSV::VERSION.frozen?)
|
assert(CSV::VERSION.frozen?)
|
||||||
assert_match(/\A\d\.\d\.\d\Z/, CSV::VERSION)
|
assert_match(/\A\d\.\d\.\d\Z/, CSV::VERSION)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_accepts_comment_skip_lines_option
|
||||||
|
assert_nothing_raised(ArgumentError) do
|
||||||
|
CSV.new nil, :skip_lines => /\A\s*#/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_accepts_comment_defaults_to_nil
|
||||||
|
c = CSV.new nil
|
||||||
|
assert_equal c.skip_lines, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
class RegexStub
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_requires_skip_lines_to_call_match
|
||||||
|
regex_stub = RegexStub.new
|
||||||
|
assert_raise(ArgumentError) do
|
||||||
|
CSV.new nil, :skip_lines => regex_stub
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_comment_rows_are_ignored
|
||||||
|
sample_data = "line,1,a\n#not,a,line\nline,2,b\n #also,no,line"
|
||||||
|
c = CSV.new sample_data, :skip_lines => /\A\s*#/
|
||||||
|
assert_equal c.each.to_a, [["line", "1", "a"], ["line", "2", "b"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_quoted_skip_line_markers_are_ignored
|
||||||
|
sample_data = "line,1,a\n\"#not\",a,line\nline,2,b"
|
||||||
|
c = CSV.new sample_data, :skip_lines => /\A\s*#/
|
||||||
|
assert_equal c.each.to_a, [["line", "1", "a"], ["#not", "a", "line"], ["line", "2", "b"]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue