aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeg2 <jeg2@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-20 20:52:36 +0000
committerjeg2 <jeg2@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-20 20:52:36 +0000
commit3c3e659196b7511f02b03e2904c40a29993a184c (patch)
tree7ed24f6ae43d6ecac69602d97e15039768f75059
parent6ac1d39acec4ccb01cca219e30d2ba4b3547a9e3 (diff)
downloadruby-3c3e659196b7511f02b03e2904c40a29993a184c.tar.gz
* 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
-rw-r--r--ChangeLog11
-rw-r--r--lib/csv.rb25
-rwxr-xr-xtest/csv/test_features.rb33
3 files changed, 66 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index adbe9e6593..bde75d9e7a 100644
--- a/ChangeLog
+++ b/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>
- * re.c (rb_reg_initialize_m): Forgot to update output for or'd-options
- example.
+ * re.c (rb_reg_initialize_m): Forgot to update output for or'd-options
+ example.
Tue Aug 21 05:18:03 2012 Eric Hodel <drbrain@segment7.net>
diff --git a/lib/csv.rb b/lib/csv.rb
index 13f86ec318..45da2c9bd6 100644
--- a/lib/csv.rb
+++ b/lib/csv.rb
@@ -973,6 +973,7 @@ class CSV
# <b><tt>:header_converters</tt></b>:: +nil+
# <b><tt>:skip_blanks</tt></b>:: +false+
# <b><tt>:force_quotes</tt></b>:: +false+
+ # <b><tt>:skip_lines</tt></b>:: +nil+
#
DEFAULT_OPTIONS = { col_sep: ",",
row_sep: :auto,
@@ -984,7 +985,8 @@ class CSV
return_headers: false,
header_converters: nil,
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
@@ -1554,6 +1556,14 @@ class CSV
# skip over any rows with no content.
# <b><tt>:force_quotes</tt></b>:: When set to a +true+ value, CSV will
# 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.
#
@@ -1591,6 +1601,7 @@ class CSV
init_parsers(options)
init_converters(options)
init_headers(options)
+ init_comments(options)
options.delete(:encoding)
options.delete(:internal_encoding)
@@ -1620,6 +1631,10 @@ class CSV
attr_reader :quote_char
# The limit for field size, if any. See CSV::new for details.
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.
# Built-in converters will be returned by name, while others will be returned
@@ -1873,6 +1888,8 @@ class CSV
end
end
+ next if @skip_lines and @skip_lines.match parse
+
parts = parse.split(@col_sep, -1)
if parts.empty?
if in_extended_col
@@ -2189,6 +2206,12 @@ class CSV
init_converters(options, :header_converters)
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
# CSV.header_convert().
diff --git a/test/csv/test_features.rb b/test/csv/test_features.rb
index 7176cca0e0..ded876abbe 100755
--- a/test/csv/test_features.rb
+++ b/test/csv/test_features.rb
@@ -274,4 +274,37 @@ class TestCSV::Features < TestCSV
assert(CSV::VERSION.frozen?)
assert_match(/\A\d\.\d\.\d\Z/, CSV::VERSION)
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