zsv 1.3.0 → 1.3.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.
- checksums.yaml +4 -4
- data/ext/zsv/extconf.rb +66 -49
- data/ext/zsv/options.c +1 -2
- data/ext/zsv/parser.c +14 -0
- data/ext/zsv/zsv_ext.c +3 -0
- data/lib/zsv/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cef0e2af9b74333c1e3d3caeeedf68d8cbd494a5df6406eb3c680277cf726d10
|
|
4
|
+
data.tar.gz: f37ffbc7e3d95640c772de7405a6f34846254173138c29ce7c140fe2d3038e29
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfa9f9e43d59a8f6c4d30e52d42da54968c88fa8866056d5be0f1ef45fdd7ad4d4f195b92f66636b752e75c5fefcfd6977a23df588720b89b2ae7c0506413338
|
|
7
|
+
data.tar.gz: 938569fa2d250c2551d8e279317e8d2c83d3ff962cca315ca98ab0528675643ca4c288310820bb24bf6d2b4491085bb1150db7f36d8221eb6e28106bf2463d2f
|
data/ext/zsv/extconf.rb
CHANGED
|
@@ -1,39 +1,53 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
3
|
+
require 'mkmf'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'uri'
|
|
6
|
+
require 'fileutils'
|
|
7
|
+
require 'rubygems/package'
|
|
8
|
+
require 'zlib'
|
|
9
|
+
require 'openssl'
|
|
9
10
|
|
|
10
11
|
# ZSV version to compile against
|
|
11
|
-
ZSV_VERSION =
|
|
12
|
+
ZSV_VERSION = '1.3.0' # zsv C library version (not gem version)
|
|
12
13
|
ZSV_URL = "https://github.com/liquidaty/zsv/archive/refs/tags/v#{ZSV_VERSION}.tar.gz".freeze
|
|
13
14
|
# Use absolute path relative to the original extconf.rb location
|
|
14
15
|
EXTCONF_DIR = File.expand_path(__dir__)
|
|
15
|
-
VENDOR_DIR = File.join(EXTCONF_DIR,
|
|
16
|
+
VENDOR_DIR = File.join(EXTCONF_DIR, 'vendor')
|
|
16
17
|
ZSV_DIR = File.join(VENDOR_DIR, "zsv-#{ZSV_VERSION}")
|
|
17
18
|
|
|
18
|
-
def download_file(url, destination)
|
|
19
|
+
def download_file(url, destination, redirect_limit = 10, verify_ssl = true)
|
|
20
|
+
abort('Too many redirects') if redirect_limit.zero?
|
|
21
|
+
|
|
19
22
|
uri = URI.parse(url)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
24
|
+
|
|
25
|
+
if uri.scheme == 'https'
|
|
26
|
+
http.use_ssl = true
|
|
27
|
+
http.verify_mode = verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
|
28
|
+
http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && verify_ssl
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
32
|
+
|
|
33
|
+
begin
|
|
34
|
+
response = http.request(request)
|
|
35
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
36
|
+
if verify_ssl
|
|
37
|
+
# Retry without SSL verification (GitHub is trusted)
|
|
38
|
+
warn "SSL verification failed (#{e.message}), retrying without verification..."
|
|
39
|
+
return download_file(url, destination, redirect_limit, false)
|
|
36
40
|
end
|
|
41
|
+
raise
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
case response
|
|
45
|
+
when Net::HTTPRedirection
|
|
46
|
+
download_file(response['location'], destination, redirect_limit - 1, verify_ssl)
|
|
47
|
+
when Net::HTTPSuccess
|
|
48
|
+
File.binwrite(destination, response.body)
|
|
49
|
+
else
|
|
50
|
+
abort("Failed to download: #{response.code} #{response.message}")
|
|
37
51
|
end
|
|
38
52
|
end
|
|
39
53
|
|
|
@@ -59,32 +73,32 @@ def download_and_extract_zsv
|
|
|
59
73
|
puts "Downloading zsv #{ZSV_VERSION}..."
|
|
60
74
|
FileUtils.mkdir_p(VENDOR_DIR)
|
|
61
75
|
|
|
62
|
-
tarball = File.join(VENDOR_DIR,
|
|
76
|
+
tarball = File.join(VENDOR_DIR, 'zsv.tar.gz')
|
|
63
77
|
download_file(ZSV_URL, tarball)
|
|
64
78
|
|
|
65
|
-
puts
|
|
79
|
+
puts 'Extracting zsv...'
|
|
66
80
|
extract_tar_gz(tarball, VENDOR_DIR)
|
|
67
81
|
FileUtils.rm_f(tarball)
|
|
68
82
|
|
|
69
|
-
abort(
|
|
83
|
+
abort('zsv directory not found after extraction') unless File.directory?(ZSV_DIR)
|
|
70
84
|
puts "zsv #{ZSV_VERSION} downloaded successfully"
|
|
71
85
|
end
|
|
72
86
|
|
|
73
87
|
def build_zsv
|
|
74
|
-
puts
|
|
88
|
+
puts 'Building zsv library...'
|
|
75
89
|
|
|
76
90
|
# Build zsv static library
|
|
77
91
|
Dir.chdir(ZSV_DIR) do
|
|
78
92
|
# Configure zsv
|
|
79
|
-
system(
|
|
93
|
+
system('./configure') or abort('Failed to configure zsv') unless File.exist?('config.mk')
|
|
80
94
|
|
|
81
95
|
# Build the library
|
|
82
|
-
Dir.chdir(
|
|
83
|
-
system(
|
|
96
|
+
Dir.chdir('src') do
|
|
97
|
+
system('make', 'build') or abort('Failed to build zsv library')
|
|
84
98
|
end
|
|
85
99
|
end
|
|
86
100
|
|
|
87
|
-
puts
|
|
101
|
+
puts 'zsv library built successfully'
|
|
88
102
|
end
|
|
89
103
|
|
|
90
104
|
# Download and build zsv
|
|
@@ -93,45 +107,48 @@ build_zsv
|
|
|
93
107
|
|
|
94
108
|
# Determine build directory based on platform
|
|
95
109
|
platform_dir = if RUBY_PLATFORM =~ /darwin/
|
|
96
|
-
|
|
110
|
+
'Darwin'
|
|
97
111
|
elsif RUBY_PLATFORM =~ /linux/
|
|
98
|
-
|
|
112
|
+
'Linux'
|
|
99
113
|
else
|
|
100
|
-
|
|
114
|
+
'generic'
|
|
101
115
|
end
|
|
102
116
|
|
|
103
|
-
# Find the built library
|
|
104
|
-
|
|
105
|
-
|
|
117
|
+
# Find the built library - compiler name varies (gcc, gcc-14, clang, etc.)
|
|
118
|
+
# Search for libzsv.a in the build directory
|
|
119
|
+
build_rel_dir = File.join(ZSV_DIR, 'build', platform_dir, 'rel')
|
|
120
|
+
zsv_lib = Dir.glob(File.join(build_rel_dir, '*', 'lib', 'libzsv.a')).first
|
|
121
|
+
|
|
122
|
+
abort("libzsv.a not found in #{build_rel_dir}/*/lib/") unless zsv_lib && File.exist?(zsv_lib)
|
|
106
123
|
|
|
107
|
-
|
|
124
|
+
zsv_lib_dir = File.dirname(zsv_lib)
|
|
108
125
|
|
|
109
126
|
# Add zsv include path
|
|
110
|
-
include_dir = File.join(ZSV_DIR,
|
|
127
|
+
include_dir = File.join(ZSV_DIR, 'include')
|
|
111
128
|
|
|
112
129
|
# Add compiler and linker flags
|
|
113
130
|
$INCFLAGS << " -I#{include_dir}"
|
|
114
|
-
$CFLAGS <<
|
|
115
|
-
$CFLAGS <<
|
|
131
|
+
$CFLAGS << ' -std=c99 -Wall -Wextra'
|
|
132
|
+
$CFLAGS << ' -O3' # Optimization level
|
|
116
133
|
|
|
117
134
|
# Configure include and lib paths
|
|
118
|
-
dir_config(
|
|
135
|
+
dir_config('zsv', include_dir, zsv_lib_dir)
|
|
119
136
|
|
|
120
137
|
# Find zsv header
|
|
121
|
-
abort("zsv.h not found in #{include_dir}") unless have_header(
|
|
138
|
+
abort("zsv.h not found in #{include_dir}") unless have_header('zsv.h')
|
|
122
139
|
|
|
123
140
|
# Link the static library
|
|
124
141
|
$LOCAL_LIBS << " #{zsv_lib}"
|
|
125
142
|
|
|
126
143
|
# Platform-specific adjustments
|
|
127
144
|
if RUBY_PLATFORM =~ /darwin/
|
|
128
|
-
$LDFLAGS <<
|
|
145
|
+
$LDFLAGS << ' -framework Foundation'
|
|
129
146
|
elsif RUBY_PLATFORM =~ /linux/
|
|
130
|
-
$LIBS <<
|
|
147
|
+
$LIBS << ' -lpthread -lm'
|
|
131
148
|
end
|
|
132
149
|
|
|
133
150
|
# Check for Ruby 3.2+ hash capacity preallocation
|
|
134
|
-
have_func(
|
|
151
|
+
have_func('rb_hash_new_capa')
|
|
135
152
|
|
|
136
153
|
# Create Makefile
|
|
137
|
-
create_makefile(
|
|
154
|
+
create_makefile('zsv/zsv')
|
data/ext/zsv/options.c
CHANGED
|
@@ -106,8 +106,7 @@ void zsv_options_parse(VALUE opts_hash, zsv_ruby_options_t *opts)
|
|
|
106
106
|
|
|
107
107
|
void zsv_options_free(zsv_ruby_options_t *opts)
|
|
108
108
|
{
|
|
109
|
-
/* Currently no dynamic allocations to free */
|
|
110
|
-
/* This is here for future extensibility */
|
|
109
|
+
(void)opts; /* Currently no dynamic allocations to free */
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
void zsv_options_apply(zsv_parser parser, zsv_ruby_options_t *opts)
|
data/ext/zsv/parser.c
CHANGED
|
@@ -135,6 +135,20 @@ zsv_ruby_parser_t *zsv_parser_new_from_string(VALUE string, VALUE opts_hash)
|
|
|
135
135
|
const char *str_ptr = RSTRING_PTR(string);
|
|
136
136
|
size_t str_len = RSTRING_LEN(string);
|
|
137
137
|
|
|
138
|
+
/* Handle empty string - fmemopen(ptr, 0, ...) fails on macOS */
|
|
139
|
+
if (str_len == 0) {
|
|
140
|
+
parser->file = NULL;
|
|
141
|
+
parser->closed = true;
|
|
142
|
+
parser->eof_reached = true;
|
|
143
|
+
zsv_options_parse(opts_hash, &parser->options);
|
|
144
|
+
parser->row_builder = zsv_row_builder_new(parser->options.encoding);
|
|
145
|
+
parser->row_buffer = rb_ary_new();
|
|
146
|
+
parser->headers = Qnil;
|
|
147
|
+
parser->current_row = Qnil;
|
|
148
|
+
parser->in_cleanup = false;
|
|
149
|
+
return parser;
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
parser->file = fmemopen((void *)str_ptr, str_len, "rb");
|
|
139
153
|
if (!parser->file) {
|
|
140
154
|
xfree(parser);
|
data/ext/zsv/zsv_ext.c
CHANGED
|
@@ -223,6 +223,7 @@ static VALUE rb_zsv_foreach(int argc, VALUE *argv, VALUE klass)
|
|
|
223
223
|
static VALUE rb_zsv_parse(int argc, VALUE *argv, VALUE klass)
|
|
224
224
|
{
|
|
225
225
|
VALUE string, opts;
|
|
226
|
+
(void)klass;
|
|
226
227
|
rb_scan_args(argc, argv, "11", &string, &opts);
|
|
227
228
|
|
|
228
229
|
Check_Type(string, T_STRING);
|
|
@@ -248,6 +249,7 @@ static VALUE rb_zsv_parse(int argc, VALUE *argv, VALUE klass)
|
|
|
248
249
|
static VALUE rb_zsv_read(int argc, VALUE *argv, VALUE klass)
|
|
249
250
|
{
|
|
250
251
|
VALUE path, opts;
|
|
252
|
+
(void)klass;
|
|
251
253
|
rb_scan_args(argc, argv, "11", &path, &opts);
|
|
252
254
|
|
|
253
255
|
Check_Type(path, T_STRING);
|
|
@@ -275,6 +277,7 @@ static VALUE rb_zsv_read(int argc, VALUE *argv, VALUE klass)
|
|
|
275
277
|
static VALUE rb_zsv_open(int argc, VALUE *argv, VALUE klass)
|
|
276
278
|
{
|
|
277
279
|
VALUE path, mode, opts;
|
|
280
|
+
(void)klass;
|
|
278
281
|
rb_scan_args(argc, argv, "11:", &path, &mode, &opts);
|
|
279
282
|
|
|
280
283
|
Check_Type(path, T_STRING);
|
data/lib/zsv/version.rb
CHANGED