bamfcsv 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +35 -0
- data/README +3 -0
- data/Rakefile +4 -0
- data/bamfcsv.gemspec +26 -0
- data/ext/bamfcsv/bamfcsv_ext.c +191 -0
- data/ext/bamfcsv/bamfcsv_ext.h +19 -0
- data/ext/bamfcsv/extconf.rb +2 -0
- data/lib/bamfcsv.rb +13 -0
- data/lib/bamfcsv/version.rb +3 -0
- data/spec/fixtures/bamf-comma-comma.csv +1 -0
- data/spec/fixtures/double-quotes.csv +3 -0
- data/spec/fixtures/empty.csv +0 -0
- data/spec/fixtures/escapes.csv +2 -0
- data/spec/fixtures/one-column.csv +2 -0
- data/spec/fixtures/terminated-with-cr.csv +2 -0
- data/spec/fixtures/test.csv +3 -0
- data/spec/lib/bamfcsv_spec.rb +49 -0
- data/spec/spec_helper.rb +12 -0
- data/tasks/compile.rake +11 -0
- data/tasks/rspec.rake +12 -0
- metadata +122 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bamfcsv (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
chalofa_ruby-progressbar (0.0.9.1)
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
fuubar (0.0.4)
|
12
|
+
chalofa_ruby-progressbar (~> 0.0.9)
|
13
|
+
rspec (~> 2.0)
|
14
|
+
rspec-instafail (~> 0.1.4)
|
15
|
+
rake (0.8.7)
|
16
|
+
rake-compiler (0.7.6)
|
17
|
+
rake
|
18
|
+
rspec (2.5.0)
|
19
|
+
rspec-core (~> 2.5.0)
|
20
|
+
rspec-expectations (~> 2.5.0)
|
21
|
+
rspec-mocks (~> 2.5.0)
|
22
|
+
rspec-core (2.5.1)
|
23
|
+
rspec-expectations (2.5.0)
|
24
|
+
diff-lcs (~> 1.1.2)
|
25
|
+
rspec-instafail (0.1.7)
|
26
|
+
rspec-mocks (2.5.0)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bamfcsv!
|
33
|
+
fuubar (~> 0.0.2)
|
34
|
+
rake-compiler (~> 0.7.1)
|
35
|
+
rspec (~> 2.5.0)
|
data/README
ADDED
data/Rakefile
ADDED
data/bamfcsv.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "bamfcsv/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "bamfcsv"
|
7
|
+
s.version = BAMFCSV::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jon Distad", "Alex Redington"]
|
10
|
+
s.email = ["jon@thinkrelevance.com", "lovemachine@thinkrelevance.com"]
|
11
|
+
s.homepage = "https://github.com/jondistad/bamfcsv"
|
12
|
+
s.summary = %q{BAMF!!! Your csv is parsed.}
|
13
|
+
s.description = %q{BAMFCSV parses csv like a BAMF. BAMF!!}
|
14
|
+
|
15
|
+
s.rubyforge_project = "bamfcsv"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib", "ext"]
|
21
|
+
s.extensions = %w{ext/bamfcsv/extconf.rb}
|
22
|
+
|
23
|
+
s.add_development_dependency "rspec", "~> 2.5.0"
|
24
|
+
s.add_development_dependency "fuubar", "~> 0.0.2"
|
25
|
+
s.add_development_dependency 'rake-compiler', "~> 0.7.1"
|
26
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <ruby/ruby.h>
|
3
|
+
#include <fcntl.h>
|
4
|
+
#include <sys/mman.h>
|
5
|
+
#include "bamfcsv_ext.h"
|
6
|
+
|
7
|
+
struct s_Row *alloc_row() {
|
8
|
+
|
9
|
+
struct s_Row *new_row = malloc(sizeof(struct s_Row));
|
10
|
+
|
11
|
+
new_row -> first_cell = 0;
|
12
|
+
new_row -> next_row = 0;
|
13
|
+
new_row -> cell_count = 0;
|
14
|
+
|
15
|
+
return new_row;
|
16
|
+
|
17
|
+
}
|
18
|
+
|
19
|
+
struct s_Cell *alloc_cell() {
|
20
|
+
|
21
|
+
struct s_Cell *new_cell = malloc(sizeof(struct s_Cell));
|
22
|
+
|
23
|
+
new_cell -> start = 0;
|
24
|
+
new_cell -> len = 0;
|
25
|
+
new_cell -> next_cell = 0;
|
26
|
+
new_cell -> has_quotes = 0;
|
27
|
+
|
28
|
+
return new_cell;
|
29
|
+
|
30
|
+
}
|
31
|
+
|
32
|
+
void free_cell(struct s_Cell *cell) {
|
33
|
+
|
34
|
+
if (cell != 0) {
|
35
|
+
free_cell(cell->next_cell);
|
36
|
+
free(cell);
|
37
|
+
}
|
38
|
+
|
39
|
+
}
|
40
|
+
|
41
|
+
void free_row(struct s_Row *row) {
|
42
|
+
|
43
|
+
if (row != 0) {
|
44
|
+
|
45
|
+
free_row(row->next_row);
|
46
|
+
free_cell(row->first_cell);
|
47
|
+
free(row);
|
48
|
+
|
49
|
+
}
|
50
|
+
|
51
|
+
}
|
52
|
+
|
53
|
+
VALUE build_matrix_from_pointer_tree(struct s_Row *first_row, int num_rows) {
|
54
|
+
VALUE matrix;
|
55
|
+
VALUE row;
|
56
|
+
VALUE new_string;
|
57
|
+
int i,j;
|
58
|
+
struct s_Row *cur_row;
|
59
|
+
struct s_Cell *cur_cell;
|
60
|
+
|
61
|
+
cur_row = first_row;
|
62
|
+
matrix = rb_ary_new2(num_rows);
|
63
|
+
|
64
|
+
ID gsub = rb_intern("gsub!");
|
65
|
+
VALUE dquote = rb_str_new2("\"\""), quote = rb_str_new2("\"");
|
66
|
+
|
67
|
+
for (i = 0; i < num_rows; i++) {
|
68
|
+
|
69
|
+
cur_cell = cur_row->first_cell;
|
70
|
+
row = rb_ary_new2(cur_row->cell_count);
|
71
|
+
rb_ary_store(matrix,i,row);
|
72
|
+
for (j = 0; j < cur_row->cell_count; j++) {
|
73
|
+
if (*(cur_cell->start) == '"'
|
74
|
+
&& *((cur_cell->start)+((cur_cell->len-1)*sizeof(char))) == '"')
|
75
|
+
new_string = rb_str_new(cur_cell->start+sizeof(char), cur_cell->len-(sizeof(char)*2));
|
76
|
+
else
|
77
|
+
new_string = rb_str_new(cur_cell->start, cur_cell->len);
|
78
|
+
if (cur_cell->has_quotes) {
|
79
|
+
rb_funcall(new_string, gsub, 2, dquote, quote);
|
80
|
+
}
|
81
|
+
rb_ary_store(row, j, new_string);
|
82
|
+
cur_cell = cur_cell->next_cell;
|
83
|
+
}
|
84
|
+
cur_row = cur_row->next_row;
|
85
|
+
}
|
86
|
+
|
87
|
+
return matrix;
|
88
|
+
}
|
89
|
+
|
90
|
+
void finalize_cell(struct s_Cell *cell, char *cur) {
|
91
|
+
if (*(cur-sizeof(char)) == '\r')
|
92
|
+
cell->len = cur-(cell->start)-sizeof(char);
|
93
|
+
else
|
94
|
+
cell->len = cur-(cell->start);
|
95
|
+
}
|
96
|
+
|
97
|
+
VALUE build_matrix(char *buf, int bufsize) {
|
98
|
+
int str_start = 0;
|
99
|
+
int num_rows = 1;
|
100
|
+
int in_quote = 0;
|
101
|
+
|
102
|
+
struct s_Row *first_row = alloc_row();
|
103
|
+
struct s_Row *cur_row = first_row;
|
104
|
+
struct s_Cell *cur_cell = alloc_cell();
|
105
|
+
first_row->first_cell = cur_cell;
|
106
|
+
cur_cell->start = buf;
|
107
|
+
|
108
|
+
VALUE matrix;
|
109
|
+
|
110
|
+
char *cur;
|
111
|
+
|
112
|
+
for (cur = buf; cur < buf+bufsize; cur++) {
|
113
|
+
|
114
|
+
if (*cur == '"') {
|
115
|
+
if (in_quote)
|
116
|
+
if (*(cur+1) != ',')
|
117
|
+
cur_cell->has_quotes = 1;
|
118
|
+
in_quote = !in_quote;
|
119
|
+
}
|
120
|
+
|
121
|
+
if (!in_quote) {
|
122
|
+
|
123
|
+
if (*cur == ',') {
|
124
|
+
|
125
|
+
finalize_cell(cur_cell,cur);
|
126
|
+
cur_cell->next_cell = alloc_cell();
|
127
|
+
cur_cell = cur_cell->next_cell;
|
128
|
+
cur_cell->start = cur+sizeof(char);
|
129
|
+
cur_row->cell_count += 1;
|
130
|
+
|
131
|
+
}
|
132
|
+
|
133
|
+
if (*cur == '\n') {
|
134
|
+
|
135
|
+
finalize_cell(cur_cell,cur);
|
136
|
+
cur_row->cell_count += 1;
|
137
|
+
cur_row->next_row = alloc_row();
|
138
|
+
cur_row = cur_row -> next_row;
|
139
|
+
cur_row->first_cell = alloc_cell();
|
140
|
+
cur_cell = cur_row->first_cell;
|
141
|
+
cur_cell->start = cur+sizeof(char);
|
142
|
+
|
143
|
+
num_rows++;
|
144
|
+
|
145
|
+
}
|
146
|
+
|
147
|
+
}
|
148
|
+
|
149
|
+
}
|
150
|
+
|
151
|
+
if (cur_row->cell_count == 0) {
|
152
|
+
num_rows--;
|
153
|
+
}
|
154
|
+
|
155
|
+
matrix = build_matrix_from_pointer_tree(first_row, num_rows);
|
156
|
+
|
157
|
+
free_row(first_row);
|
158
|
+
|
159
|
+
return matrix;
|
160
|
+
|
161
|
+
}
|
162
|
+
|
163
|
+
VALUE mm_parse(const char *file) {
|
164
|
+
|
165
|
+
char *mmapped_csv;
|
166
|
+
int filesize, csv;
|
167
|
+
|
168
|
+
csv = open(file, O_RDONLY);
|
169
|
+
filesize = lseek(csv, 0, SEEK_END);
|
170
|
+
mmapped_csv = (char*) mmap(0, filesize, PROT_READ, MAP_SHARED, csv, 0);
|
171
|
+
|
172
|
+
VALUE matrix = build_matrix(mmapped_csv,filesize);
|
173
|
+
|
174
|
+
munmap(mmapped_csv, filesize);
|
175
|
+
close(csv);
|
176
|
+
|
177
|
+
return matrix;
|
178
|
+
}
|
179
|
+
|
180
|
+
VALUE read_path(VALUE self, VALUE file) {
|
181
|
+
|
182
|
+
return mm_parse(RSTRING_PTR(file));
|
183
|
+
|
184
|
+
}
|
185
|
+
|
186
|
+
void Init_bamfcsv() {
|
187
|
+
|
188
|
+
VALUE module = rb_define_module("BAMFCSV");
|
189
|
+
rb_define_module_function(module, "read_path", read_path, 1);
|
190
|
+
|
191
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#ifndef _BAMFCSV_EXT_H
|
2
|
+
#define _BAMFCSV_EXT_H
|
3
|
+
|
4
|
+
struct s_Row {
|
5
|
+
struct s_Cell *first_cell;
|
6
|
+
struct s_Row *next_row;
|
7
|
+
int cell_count;
|
8
|
+
};
|
9
|
+
|
10
|
+
struct s_Cell {
|
11
|
+
char *start;
|
12
|
+
int len;
|
13
|
+
int has_quotes;
|
14
|
+
struct s_Cell *next_cell;
|
15
|
+
};
|
16
|
+
|
17
|
+
void Init_bamfcsv();
|
18
|
+
|
19
|
+
#endif
|
data/lib/bamfcsv.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bamfcsv/bamfcsv'
|
2
|
+
|
3
|
+
module BAMFCSV
|
4
|
+
|
5
|
+
def self.read(thing_to_read)
|
6
|
+
if String === thing_to_read
|
7
|
+
raise Errno::ENOENT.new("#{thing_to_read} does not exist") unless File.exist? thing_to_read
|
8
|
+
raise Errno::EISDIR.new("#{thing_to_read} is a directory") if File.directory? thing_to_read
|
9
|
+
read_path(thing_to_read)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
BAMF,,CSV
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BAMFCSV do
|
4
|
+
it "has a parse method" do
|
5
|
+
BAMFCSV.should respond_to(:read)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#read" do
|
9
|
+
it "is a matrix given a filename" do
|
10
|
+
BAMFCSV.read("spec/fixtures/test.csv").should be_instance_of Array
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is an empty array passed an empty file" do
|
14
|
+
BAMFCSV.read("spec/fixtures/empty.csv").should == []
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is a 1xn matrix with a one column csv file" do
|
18
|
+
BAMFCSV.read("spec/fixtures/one-column.csv").should == [["BAMF"],["CSV"]]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "interprets empty cells correctly" do
|
22
|
+
BAMFCSV.read("spec/fixtures/bamf-comma-comma.csv").should == [["BAMF","","CSV"]]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "escapes cells that are quoted" do
|
26
|
+
BAMFCSV.read("spec/fixtures/escapes.csv").should == [["this is a semicolon:", " ;"],["this is a comma:", " ,"]]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "escapes cells that are quoted" do
|
30
|
+
BAMFCSV.read("spec/fixtures/double-quotes.csv").should == [["this is a semicolon:", " ;"], ["this is a comma:", " ,"], ["this is a quote:", " \""]]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "doesn't create a row when the file terminates with [CR]LF" do
|
34
|
+
BAMFCSV.read("spec/fixtures/terminated-with-cr.csv").should == [["a"],["b"]]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises Errno::ENOENT when the file does not exist" do
|
38
|
+
expect do
|
39
|
+
BAMFCSV.read("spec/fixtures/this-file-does-not-not-exist.csv")
|
40
|
+
end.should raise_error Errno::ENOENT
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises Errno::EISDIR when the file is not a flat file" do
|
44
|
+
expect do
|
45
|
+
BAMFCSV.read("spec/fixtures/")
|
46
|
+
end.should raise_error Errno::EISDIR
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
root_path = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
2
|
+
$:.unshift(File.join(root_path, "lib"))
|
3
|
+
$:.unshift(File.join(root_path, "ext"))
|
4
|
+
require 'bundler'
|
5
|
+
require 'bamfcsv'
|
6
|
+
Bundler.require(:development)
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.filter_run :focused => true
|
10
|
+
config.alias_example_to :fit, :focused => true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
end
|
data/tasks/compile.rake
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require "rake/extensiontask"
|
2
|
+
|
3
|
+
def gemspec
|
4
|
+
@clean_gemspec ||= eval(File.read(File.expand_path('../../bamfcsv.gemspec', __FILE__)))
|
5
|
+
end
|
6
|
+
|
7
|
+
Rake::ExtensionTask.new("bamfcsv", gemspec) do |ext|
|
8
|
+
ext.lib_dir = File.join 'lib', 'bamfcsv'
|
9
|
+
CLEAN.include "#{ext.lib_dir}/*.#{RbConfig::CONFIG['DLEXT']}"
|
10
|
+
end
|
11
|
+
Rake::Task[:spec].prerequisites << :compile
|
data/tasks/rspec.rake
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
begin
|
2
|
+
require 'rspec'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
6
|
+
t.verbose = true
|
7
|
+
end
|
8
|
+
|
9
|
+
task :default => :spec
|
10
|
+
rescue LoadError
|
11
|
+
puts "rspec, or one of its dependencies, is not available. Install it with: sudo gem install rspec"
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bamfcsv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jon Distad
|
9
|
+
- Alex Redington
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-04-01 00:00:00 -04:00
|
15
|
+
default_executable:
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rspec
|
19
|
+
prerelease: false
|
20
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
none: false
|
22
|
+
requirements:
|
23
|
+
- - ~>
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 2.5.0
|
26
|
+
type: :development
|
27
|
+
version_requirements: *id001
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: fuubar
|
30
|
+
prerelease: false
|
31
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.0.2
|
37
|
+
type: :development
|
38
|
+
version_requirements: *id002
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: rake-compiler
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.7.1
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id003
|
50
|
+
description: BAMFCSV parses csv like a BAMF. BAMF!!
|
51
|
+
email:
|
52
|
+
- jon@thinkrelevance.com
|
53
|
+
- lovemachine@thinkrelevance.com
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions:
|
57
|
+
- ext/bamfcsv/extconf.rb
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- .gitignore
|
62
|
+
- .rspec
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- README
|
66
|
+
- Rakefile
|
67
|
+
- bamfcsv.gemspec
|
68
|
+
- ext/bamfcsv/bamfcsv_ext.c
|
69
|
+
- ext/bamfcsv/bamfcsv_ext.h
|
70
|
+
- ext/bamfcsv/extconf.rb
|
71
|
+
- lib/bamfcsv.rb
|
72
|
+
- lib/bamfcsv/version.rb
|
73
|
+
- spec/fixtures/bamf-comma-comma.csv
|
74
|
+
- spec/fixtures/double-quotes.csv
|
75
|
+
- spec/fixtures/empty.csv
|
76
|
+
- spec/fixtures/escapes.csv
|
77
|
+
- spec/fixtures/one-column.csv
|
78
|
+
- spec/fixtures/terminated-with-cr.csv
|
79
|
+
- spec/fixtures/test.csv
|
80
|
+
- spec/lib/bamfcsv_spec.rb
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
- tasks/compile.rake
|
83
|
+
- tasks/rspec.rake
|
84
|
+
has_rdoc: true
|
85
|
+
homepage: https://github.com/jondistad/bamfcsv
|
86
|
+
licenses: []
|
87
|
+
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
- ext
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: "0"
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: "0"
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project: bamfcsv
|
109
|
+
rubygems_version: 1.6.2
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: BAMF!!! Your csv is parsed.
|
113
|
+
test_files:
|
114
|
+
- spec/fixtures/bamf-comma-comma.csv
|
115
|
+
- spec/fixtures/double-quotes.csv
|
116
|
+
- spec/fixtures/empty.csv
|
117
|
+
- spec/fixtures/escapes.csv
|
118
|
+
- spec/fixtures/one-column.csv
|
119
|
+
- spec/fixtures/terminated-with-cr.csv
|
120
|
+
- spec/fixtures/test.csv
|
121
|
+
- spec/lib/bamfcsv_spec.rb
|
122
|
+
- spec/spec_helper.rb
|