smarter_csv 1.14.3 → 1.14.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/CONTRIBUTORS.md +1 -0
- data/lib/smarter_csv/auto_detection.rb +1 -1
- data/lib/smarter_csv/version.rb +1 -1
- metadata +2 -14
- data/ext/smarter_csv/Makefile +0 -270
- data/ext/smarter_csv/smarter_csv.c.works +0 -185
- data/ext/smarter_csv/smarter_csv.c.works10 +0 -199
- data/ext/smarter_csv/smarter_csv.c.works11 +0 -189
- data/ext/smarter_csv/smarter_csv.c.works14 +0 -230
- data/ext/smarter_csv/smarter_csv.c.works15 +0 -230
- data/ext/smarter_csv/smarter_csv.c.works2 +0 -192
- data/ext/smarter_csv/smarter_csv.c.works4 +0 -190
- data/ext/smarter_csv/smarter_csv.c.works5 +0 -203
- data/ext/smarter_csv/smarter_csv.c.works7 +0 -217
- data/ext/smarter_csv/smarter_csv.c.works8 +0 -193
- data/ext/smarter_csv/smarter_csv.c.works9 +0 -196
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a84cfa57008a6f9f05ee82eeef9edb4dab5993874a38c456ce78d8da999280aa
|
4
|
+
data.tar.gz: 7e8569670615a6ff7fb63c152d8e849069bcde318edf885d95cef52b5513f52c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d1baa73a0120824390f062e38d3acab8dfc7a09d48fbbdd647466605ccd543ca839e61cbefca9929d2dafce9a61b12e50b62d9e034aadd047a46e1886728980
|
7
|
+
data.tar.gz: 9756f2fdd15e619ba98011370a3410781b7771edd0656dd1bcb1226ebf899726ec00f43627dcc16756d986a962e9eb3e84c7e901ef5aecf12ede9f077f7a8423
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
|
2
2
|
# SmarterCSV 1.x Change Log
|
3
3
|
|
4
|
+
## 1.14.4 (2025-05-26)
|
5
|
+
* Bugfix: SmarterCSV::Reader fixing issue with header containing spaces ([PR 305](https://github.com/tilo/smarter_csv/pull/305) thanks to Felipe Cabezudo)
|
6
|
+
|
4
7
|
## 1.14.3 (2025-05-04)
|
5
8
|
* Improved C-extension parsing logic:
|
6
9
|
- Added fast path for unquoted fields to avoid unnecessary quote checks.
|
data/CONTRIBUTORS.md
CHANGED
@@ -59,3 +59,4 @@ A Big Thank you to everyone who filed issues, sent comments, and who contributed
|
|
59
59
|
* [Randall B](https://github.com/randall-coding)
|
60
60
|
* [Matthew Kennedy](https://github.com/MattKitmanLabs)
|
61
61
|
* [Robert Reiz](https://github.com/reiz)
|
62
|
+
* [Felipe Cabezudo](https://github.com/felipekb)
|
data/lib/smarter_csv/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smarter_csv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.14.
|
4
|
+
version: 1.14.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tilo Sloboda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|
@@ -127,20 +127,8 @@ files:
|
|
127
127
|
- docs/options.md
|
128
128
|
- docs/row_col_sep.md
|
129
129
|
- docs/value_converters.md
|
130
|
-
- ext/smarter_csv/Makefile
|
131
130
|
- ext/smarter_csv/extconf.rb
|
132
131
|
- ext/smarter_csv/smarter_csv.c
|
133
|
-
- ext/smarter_csv/smarter_csv.c.works
|
134
|
-
- ext/smarter_csv/smarter_csv.c.works10
|
135
|
-
- ext/smarter_csv/smarter_csv.c.works11
|
136
|
-
- ext/smarter_csv/smarter_csv.c.works14
|
137
|
-
- ext/smarter_csv/smarter_csv.c.works15
|
138
|
-
- ext/smarter_csv/smarter_csv.c.works2
|
139
|
-
- ext/smarter_csv/smarter_csv.c.works4
|
140
|
-
- ext/smarter_csv/smarter_csv.c.works5
|
141
|
-
- ext/smarter_csv/smarter_csv.c.works7
|
142
|
-
- ext/smarter_csv/smarter_csv.c.works8
|
143
|
-
- ext/smarter_csv/smarter_csv.c.works9
|
144
132
|
- lib/smarter_csv.rb
|
145
133
|
- lib/smarter_csv/auto_detection.rb
|
146
134
|
- lib/smarter_csv/errors.rb
|
data/ext/smarter_csv/Makefile
DELETED
@@ -1,270 +0,0 @@
|
|
1
|
-
|
2
|
-
SHELL = /bin/sh
|
3
|
-
|
4
|
-
# V=0 quiet, V=1 verbose. other values don't work.
|
5
|
-
V = 0
|
6
|
-
V0 = $(V:0=)
|
7
|
-
Q1 = $(V:1=)
|
8
|
-
Q = $(Q1:0=@)
|
9
|
-
ECHO1 = $(V:1=@ :)
|
10
|
-
ECHO = $(ECHO1:0=@ echo)
|
11
|
-
NULLCMD = :
|
12
|
-
|
13
|
-
#### Start of system configuration section. ####
|
14
|
-
|
15
|
-
srcdir = .
|
16
|
-
topdir = /Users/tilo/.rvm/rubies/ruby-3.2.2/include/ruby-3.2.0
|
17
|
-
hdrdir = $(topdir)
|
18
|
-
arch_hdrdir = /Users/tilo/.rvm/rubies/ruby-3.2.2/include/ruby-3.2.0/arm64-darwin23
|
19
|
-
PATH_SEPARATOR = :
|
20
|
-
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
21
|
-
prefix = $(DESTDIR)/Users/tilo/.rvm/rubies/ruby-3.2.2
|
22
|
-
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
|
23
|
-
rubyarchprefix = $(rubylibprefix)/$(arch)
|
24
|
-
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
|
25
|
-
exec_prefix = $(prefix)
|
26
|
-
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
|
27
|
-
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
|
28
|
-
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
|
29
|
-
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
30
|
-
sitehdrdir = $(rubyhdrdir)/site_ruby
|
31
|
-
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
|
32
|
-
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
33
|
-
vendorlibdir = $(vendordir)/$(ruby_version)
|
34
|
-
vendordir = $(rubylibprefix)/vendor_ruby
|
35
|
-
sitearchdir = $(sitelibdir)/$(sitearch)
|
36
|
-
sitelibdir = $(sitedir)/$(ruby_version)
|
37
|
-
sitedir = $(rubylibprefix)/site_ruby
|
38
|
-
rubyarchdir = $(rubylibdir)/$(arch)
|
39
|
-
rubylibdir = $(rubylibprefix)/$(ruby_version)
|
40
|
-
sitearchincludedir = $(includedir)/$(sitearch)
|
41
|
-
archincludedir = $(includedir)/$(arch)
|
42
|
-
sitearchlibdir = $(libdir)/$(sitearch)
|
43
|
-
archlibdir = $(libdir)/$(arch)
|
44
|
-
ridir = $(datarootdir)/$(RI_BASE_NAME)
|
45
|
-
mandir = $(datarootdir)/man
|
46
|
-
localedir = $(datarootdir)/locale
|
47
|
-
libdir = $(exec_prefix)/lib
|
48
|
-
psdir = $(docdir)
|
49
|
-
pdfdir = $(docdir)
|
50
|
-
dvidir = $(docdir)
|
51
|
-
htmldir = $(docdir)
|
52
|
-
infodir = $(datarootdir)/info
|
53
|
-
docdir = $(datarootdir)/doc/$(PACKAGE)
|
54
|
-
oldincludedir = $(DESTDIR)/usr/include
|
55
|
-
includedir = $(SDKROOT)$(prefix)/include
|
56
|
-
runstatedir = $(localstatedir)/run
|
57
|
-
localstatedir = $(prefix)/var
|
58
|
-
sharedstatedir = $(prefix)/com
|
59
|
-
sysconfdir = $(prefix)/etc
|
60
|
-
datadir = $(datarootdir)
|
61
|
-
datarootdir = $(prefix)/share
|
62
|
-
libexecdir = $(exec_prefix)/libexec
|
63
|
-
sbindir = $(exec_prefix)/sbin
|
64
|
-
bindir = $(exec_prefix)/bin
|
65
|
-
archdir = $(rubyarchdir)
|
66
|
-
|
67
|
-
|
68
|
-
CC_WRAPPER =
|
69
|
-
CC = gcc
|
70
|
-
CXX = g++
|
71
|
-
LIBRUBY = $(LIBRUBY_SO)
|
72
|
-
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
73
|
-
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
74
|
-
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation $(MAINLIBS)
|
75
|
-
empty =
|
76
|
-
OUTFLAG = -o $(empty)
|
77
|
-
COUTFLAG = -o $(empty)
|
78
|
-
CSRCFLAG = $(empty)
|
79
|
-
|
80
|
-
RUBY_EXTCONF_H =
|
81
|
-
cflags = -fdeclspec $(optflags) $(debugflags) $(warnflags)
|
82
|
-
cxxflags =
|
83
|
-
optflags = -O3
|
84
|
-
debugflags = -ggdb3
|
85
|
-
warnflags = -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wundef
|
86
|
-
cppflags =
|
87
|
-
CCDLFLAGS = -fno-common
|
88
|
-
CFLAGS = $(CCDLFLAGS) -O3 -I/opt/homebrew/opt/libyaml/include -I/opt/homebrew/opt/libksba/include -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/zlib/include -I/opt/homebrew/opt/openssl@1.1/include $(cflags) -fno-common -pipe $(ARCH_FLAG)
|
89
|
-
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
90
|
-
DEFS =
|
91
|
-
CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags)
|
92
|
-
CXXFLAGS = $(CCDLFLAGS) -fdeclspec $(ARCH_FLAG)
|
93
|
-
ldflags = -L. -L/opt/homebrew/opt/libyaml/lib -L/opt/homebrew/opt/libksba/lib -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/zlib/lib -L/opt/homebrew/opt/openssl@1.1/lib -fstack-protector-strong
|
94
|
-
dldflags = -L/opt/homebrew/opt/libyaml/lib -L/opt/homebrew/opt/libksba/lib -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/zlib/lib -L/opt/homebrew/opt/openssl@1.1/lib -Wl,-undefined,dynamic_lookup $(LIBRUBYARG_SHARED)
|
95
|
-
ARCH_FLAG =
|
96
|
-
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
97
|
-
LDSHARED = $(CC) -dynamic -bundle
|
98
|
-
LDSHAREDXX = $(CXX) -dynamic -bundle
|
99
|
-
AR = ar
|
100
|
-
EXEEXT =
|
101
|
-
|
102
|
-
RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
|
103
|
-
RUBY_SO_NAME = ruby.3.2
|
104
|
-
RUBYW_INSTALL_NAME =
|
105
|
-
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
|
106
|
-
RUBYW_BASE_NAME = rubyw
|
107
|
-
RUBY_BASE_NAME = ruby
|
108
|
-
|
109
|
-
arch = arm64-darwin23
|
110
|
-
sitearch = $(arch)
|
111
|
-
ruby_version = 3.2.0
|
112
|
-
ruby = $(bindir)/$(RUBY_BASE_NAME)
|
113
|
-
RUBY = $(ruby)
|
114
|
-
BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME)
|
115
|
-
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
|
116
|
-
|
117
|
-
RM = rm -f
|
118
|
-
RM_RF = rm -fr
|
119
|
-
RMDIRS = rmdir -p
|
120
|
-
MAKEDIRS = /opt/homebrew/opt/coreutils/bin/gmkdir -p
|
121
|
-
INSTALL = /opt/homebrew/opt/coreutils/bin/ginstall -c
|
122
|
-
INSTALL_PROG = $(INSTALL) -m 0755
|
123
|
-
INSTALL_DATA = $(INSTALL) -m 644
|
124
|
-
COPY = cp
|
125
|
-
TOUCH = exit >
|
126
|
-
|
127
|
-
#### End of system configuration section. ####
|
128
|
-
|
129
|
-
preload =
|
130
|
-
libpath = . $(libdir)
|
131
|
-
LIBPATH = -L. -L$(libdir)
|
132
|
-
DEFFILE =
|
133
|
-
|
134
|
-
CLEANFILES = mkmf.log
|
135
|
-
DISTCLEANFILES =
|
136
|
-
DISTCLEANDIRS =
|
137
|
-
|
138
|
-
extout =
|
139
|
-
extout_prefix =
|
140
|
-
target_prefix = /smarter_csv
|
141
|
-
LOCAL_LIBS =
|
142
|
-
LIBS = $(LIBRUBYARG_SHARED) -lpthread
|
143
|
-
ORIG_SRCS = smarter_csv.c
|
144
|
-
SRCS = $(ORIG_SRCS)
|
145
|
-
OBJS = smarter_csv.o
|
146
|
-
HDRS =
|
147
|
-
LOCAL_HDRS =
|
148
|
-
TARGET = smarter_csv
|
149
|
-
TARGET_NAME = smarter_csv
|
150
|
-
TARGET_ENTRY = Init_$(TARGET_NAME)
|
151
|
-
DLLIB = $(TARGET).bundle
|
152
|
-
EXTSTATIC =
|
153
|
-
STATIC_LIB =
|
154
|
-
|
155
|
-
TIMESTAMP_DIR = .
|
156
|
-
BINDIR = $(bindir)
|
157
|
-
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
158
|
-
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
159
|
-
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
160
|
-
HDRDIR = $(sitehdrdir)$(target_prefix)
|
161
|
-
ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix)
|
162
|
-
TARGET_SO_DIR =
|
163
|
-
TARGET_SO = $(TARGET_SO_DIR)$(DLLIB)
|
164
|
-
CLEANLIBS = $(TARGET_SO) $(TARGET_SO).dSYM
|
165
|
-
CLEANOBJS = $(OBJS) *.bak
|
166
|
-
TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.smarter_csv.time
|
167
|
-
|
168
|
-
all: $(DLLIB)
|
169
|
-
static: $(STATIC_LIB)
|
170
|
-
.PHONY: all install static install-so install-rb
|
171
|
-
.PHONY: clean clean-so clean-static clean-rb
|
172
|
-
|
173
|
-
clean-static::
|
174
|
-
clean-rb-default::
|
175
|
-
clean-rb::
|
176
|
-
clean-so::
|
177
|
-
clean: clean-so clean-static clean-rb-default clean-rb
|
178
|
-
-$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
|
179
|
-
|
180
|
-
distclean-rb-default::
|
181
|
-
distclean-rb::
|
182
|
-
distclean-so::
|
183
|
-
distclean-static::
|
184
|
-
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
|
185
|
-
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
186
|
-
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
187
|
-
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
|
188
|
-
|
189
|
-
realclean: distclean
|
190
|
-
install: install-so install-rb
|
191
|
-
|
192
|
-
install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP)
|
193
|
-
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
194
|
-
clean-static::
|
195
|
-
-$(Q)$(RM) $(STATIC_LIB)
|
196
|
-
install-rb: pre-install-rb do-install-rb install-rb-default
|
197
|
-
install-rb-default: pre-install-rb-default do-install-rb-default
|
198
|
-
pre-install-rb: Makefile
|
199
|
-
pre-install-rb-default: Makefile
|
200
|
-
do-install-rb:
|
201
|
-
do-install-rb-default:
|
202
|
-
pre-install-rb-default:
|
203
|
-
@$(NULLCMD)
|
204
|
-
$(TARGET_SO_DIR_TIMESTAMP):
|
205
|
-
$(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
|
206
|
-
$(Q) $(TOUCH) $@
|
207
|
-
|
208
|
-
site-install: site-install-so site-install-rb
|
209
|
-
site-install-so: install-so
|
210
|
-
site-install-rb: install-rb
|
211
|
-
|
212
|
-
.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
|
213
|
-
|
214
|
-
.cc.o:
|
215
|
-
$(ECHO) compiling $(<)
|
216
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
217
|
-
|
218
|
-
.cc.S:
|
219
|
-
$(ECHO) translating $(<)
|
220
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
221
|
-
|
222
|
-
.mm.o:
|
223
|
-
$(ECHO) compiling $(<)
|
224
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
225
|
-
|
226
|
-
.mm.S:
|
227
|
-
$(ECHO) translating $(<)
|
228
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
229
|
-
|
230
|
-
.cxx.o:
|
231
|
-
$(ECHO) compiling $(<)
|
232
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
233
|
-
|
234
|
-
.cxx.S:
|
235
|
-
$(ECHO) translating $(<)
|
236
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
237
|
-
|
238
|
-
.cpp.o:
|
239
|
-
$(ECHO) compiling $(<)
|
240
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
241
|
-
|
242
|
-
.cpp.S:
|
243
|
-
$(ECHO) translating $(<)
|
244
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
245
|
-
|
246
|
-
.c.o:
|
247
|
-
$(ECHO) compiling $(<)
|
248
|
-
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
249
|
-
|
250
|
-
.c.S:
|
251
|
-
$(ECHO) translating $(<)
|
252
|
-
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
253
|
-
|
254
|
-
.m.o:
|
255
|
-
$(ECHO) compiling $(<)
|
256
|
-
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
257
|
-
|
258
|
-
.m.S:
|
259
|
-
$(ECHO) translating $(<)
|
260
|
-
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
261
|
-
|
262
|
-
$(TARGET_SO): $(OBJS) Makefile
|
263
|
-
$(ECHO) linking shared-object smarter_csv/$(DLLIB)
|
264
|
-
-$(Q)$(RM) $(@)
|
265
|
-
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
266
|
-
$(Q) $(POSTLINK)
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
$(OBJS): $(HDRS) $(ruby_headers)
|
@@ -1,185 +0,0 @@
|
|
1
|
-
#include "ruby.h"
|
2
|
-
#include "ruby/encoding.h"
|
3
|
-
#include <stdio.h>
|
4
|
-
#include <stdbool.h>
|
5
|
-
|
6
|
-
#ifndef bool
|
7
|
-
#define bool int
|
8
|
-
#define false ((bool)0)
|
9
|
-
#define true ((bool)1)
|
10
|
-
#endif
|
11
|
-
|
12
|
-
VALUE SmarterCSV = Qnil;
|
13
|
-
VALUE eMalformedCSVError = Qnil;
|
14
|
-
VALUE Parser = Qnil;
|
15
|
-
|
16
|
-
static VALUE Qempty_string; // shared frozen empty string
|
17
|
-
|
18
|
-
static VALUE rb_parse_csv_line(VALUE self, VALUE line, VALUE col_sep, VALUE quote_char, VALUE max_size) {
|
19
|
-
if (RB_TYPE_P(line, T_NIL) == 1) {
|
20
|
-
return rb_ary_new();
|
21
|
-
}
|
22
|
-
|
23
|
-
if (RB_TYPE_P(line, T_STRING) != 1) {
|
24
|
-
rb_raise(rb_eTypeError, "ERROR in SmarterCSV.parse_line: line has to be a string or nil");
|
25
|
-
}
|
26
|
-
|
27
|
-
rb_encoding *encoding = rb_enc_get(line); /* get the encoding from the input line */
|
28
|
-
char *startP = RSTRING_PTR(line); /* may not be null terminated */
|
29
|
-
long line_len = RSTRING_LEN(line);
|
30
|
-
char *endP = startP + line_len; /* points behind the string */
|
31
|
-
char *p = startP;
|
32
|
-
|
33
|
-
char *col_sepP = RSTRING_PTR(col_sep);
|
34
|
-
long col_sep_len = RSTRING_LEN(col_sep);
|
35
|
-
|
36
|
-
char *quoteP = RSTRING_PTR(quote_char);
|
37
|
-
char quote = *quoteP;
|
38
|
-
long quote_count = 0;
|
39
|
-
|
40
|
-
bool col_sep_found = true;
|
41
|
-
|
42
|
-
VALUE elements = rb_ary_new();
|
43
|
-
VALUE field;
|
44
|
-
long i;
|
45
|
-
|
46
|
-
/* Variables for escaped quote handling */
|
47
|
-
long backslash_count = 0;
|
48
|
-
bool in_quotes = false;
|
49
|
-
|
50
|
-
/* Optimization 1: maintain count instead of calling RARRAY_LEN repeatedly */
|
51
|
-
long element_count = 0;
|
52
|
-
|
53
|
-
/* Optimization 2: cache max_size value if not nil */
|
54
|
-
int max_fields = -1;
|
55
|
-
if (max_size != Qnil) {
|
56
|
-
max_fields = NUM2INT(max_size);
|
57
|
-
if (max_fields < 0) {
|
58
|
-
return rb_ary_new(); // Return empty array early
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
while (p < endP) {
|
63
|
-
/* does the remaining string start with col_sep ? */
|
64
|
-
col_sep_found = true;
|
65
|
-
for (i = 0; (i < col_sep_len) && (p + i < endP); i++) {
|
66
|
-
col_sep_found = col_sep_found && (*(p + i) == *(col_sepP + i));
|
67
|
-
}
|
68
|
-
|
69
|
-
/* if col_sep was found and we're not inside quotes */
|
70
|
-
if (col_sep_found && !in_quotes) {
|
71
|
-
if ((max_fields >= 0) && (element_count >= max_fields)) {
|
72
|
-
break;
|
73
|
-
} else {
|
74
|
-
bool only_spaces = true;
|
75
|
-
for (char *s = startP; s < p; s++) {
|
76
|
-
if (*s != ' ') {
|
77
|
-
only_spaces = false;
|
78
|
-
break;
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
|
-
if (only_spaces) {
|
83
|
-
field = Qempty_string;
|
84
|
-
} else {
|
85
|
-
long field_len = p - startP;
|
86
|
-
|
87
|
-
// fast-path quote cleanup: if field starts and ends with quote, and no doubled quotes inside
|
88
|
-
if (field_len >= 2 && startP[0] == quote && startP[field_len - 1] == quote) {
|
89
|
-
char *inner_start = startP + 1;
|
90
|
-
long inner_len = field_len - 2;
|
91
|
-
bool has_double_quote = false;
|
92
|
-
for (i = 0; i < inner_len - 1; i++) {
|
93
|
-
if (inner_start[i] == quote && inner_start[i + 1] == quote) {
|
94
|
-
has_double_quote = true;
|
95
|
-
break;
|
96
|
-
}
|
97
|
-
}
|
98
|
-
if (!has_double_quote) {
|
99
|
-
field = rb_enc_str_new(inner_start, inner_len, encoding);
|
100
|
-
} else {
|
101
|
-
field = rb_enc_str_new(startP, field_len, encoding);
|
102
|
-
}
|
103
|
-
} else {
|
104
|
-
field = rb_enc_str_new(startP, field_len, encoding);
|
105
|
-
}
|
106
|
-
}
|
107
|
-
|
108
|
-
rb_ary_push(elements, field);
|
109
|
-
element_count++;
|
110
|
-
|
111
|
-
p += col_sep_len;
|
112
|
-
startP = p;
|
113
|
-
backslash_count = 0; // Reset backslash count at the start of a new field
|
114
|
-
}
|
115
|
-
} else {
|
116
|
-
if (*p == '\\') {
|
117
|
-
backslash_count++;
|
118
|
-
} else {
|
119
|
-
if (*p == quote) {
|
120
|
-
if (backslash_count % 2 == 0) {
|
121
|
-
in_quotes = !in_quotes;
|
122
|
-
}
|
123
|
-
}
|
124
|
-
backslash_count = 0;
|
125
|
-
}
|
126
|
-
p++;
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
|
-
if (in_quotes) {
|
131
|
-
rb_raise(eMalformedCSVError, "Unclosed quoted field detected in line: %s", StringValueCStr(line));
|
132
|
-
}
|
133
|
-
|
134
|
-
if ((max_fields < 0) || (element_count < max_fields)) {
|
135
|
-
bool only_spaces = true;
|
136
|
-
for (char *s = startP; s < endP; s++) {
|
137
|
-
if (*s != ' ') {
|
138
|
-
only_spaces = false;
|
139
|
-
break;
|
140
|
-
}
|
141
|
-
}
|
142
|
-
|
143
|
-
if (only_spaces) {
|
144
|
-
field = Qempty_string;
|
145
|
-
} else {
|
146
|
-
long field_len = endP - startP;
|
147
|
-
|
148
|
-
// fast-path quote cleanup on final field
|
149
|
-
if (field_len >= 2 && startP[0] == quote && startP[field_len - 1] == quote) {
|
150
|
-
char *inner_start = startP + 1;
|
151
|
-
long inner_len = field_len - 2;
|
152
|
-
bool has_double_quote = false;
|
153
|
-
for (i = 0; i < inner_len - 1; i++) {
|
154
|
-
if (inner_start[i] == quote && inner_start[i + 1] == quote) {
|
155
|
-
has_double_quote = true;
|
156
|
-
break;
|
157
|
-
}
|
158
|
-
}
|
159
|
-
if (!has_double_quote) {
|
160
|
-
field = rb_enc_str_new(inner_start, inner_len, encoding);
|
161
|
-
} else {
|
162
|
-
field = rb_enc_str_new(startP, field_len, encoding);
|
163
|
-
}
|
164
|
-
} else {
|
165
|
-
field = rb_enc_str_new(startP, field_len, encoding);
|
166
|
-
}
|
167
|
-
}
|
168
|
-
|
169
|
-
rb_ary_push(elements, field);
|
170
|
-
}
|
171
|
-
|
172
|
-
return elements;
|
173
|
-
}
|
174
|
-
|
175
|
-
void Init_smarter_csv(void) {
|
176
|
-
SmarterCSV = rb_const_get(rb_cObject, rb_intern("SmarterCSV"));
|
177
|
-
Parser = rb_const_get(SmarterCSV, rb_intern("Parser"));
|
178
|
-
eMalformedCSVError = rb_const_get(SmarterCSV, rb_intern("MalformedCSV"));
|
179
|
-
|
180
|
-
Qempty_string = rb_str_new_literal("");
|
181
|
-
rb_obj_freeze(Qempty_string);
|
182
|
-
rb_global_variable(&Qempty_string);
|
183
|
-
|
184
|
-
rb_define_module_function(Parser, "parse_csv_line_c", rb_parse_csv_line, 4);
|
185
|
-
}
|