fiddle 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/fiddle/pack.rb CHANGED
@@ -11,24 +11,24 @@ module Fiddle
11
11
  TYPE_LONG => ALIGN_LONG,
12
12
  TYPE_FLOAT => ALIGN_FLOAT,
13
13
  TYPE_DOUBLE => ALIGN_DOUBLE,
14
- -TYPE_CHAR => ALIGN_CHAR,
15
- -TYPE_SHORT => ALIGN_SHORT,
16
- -TYPE_INT => ALIGN_INT,
17
- -TYPE_LONG => ALIGN_LONG,
14
+ TYPE_UCHAR => ALIGN_CHAR,
15
+ TYPE_USHORT => ALIGN_SHORT,
16
+ TYPE_UINT => ALIGN_INT,
17
+ TYPE_ULONG => ALIGN_LONG,
18
18
  }
19
19
 
20
20
  PACK_MAP = {
21
- TYPE_VOIDP => "l!",
21
+ TYPE_VOIDP => "L!",
22
22
  TYPE_CHAR => "c",
23
23
  TYPE_SHORT => "s!",
24
24
  TYPE_INT => "i!",
25
25
  TYPE_LONG => "l!",
26
26
  TYPE_FLOAT => "f",
27
27
  TYPE_DOUBLE => "d",
28
- -TYPE_CHAR => "c",
29
- -TYPE_SHORT => "s!",
30
- -TYPE_INT => "i!",
31
- -TYPE_LONG => "l!",
28
+ TYPE_UCHAR => "C",
29
+ TYPE_USHORT => "S!",
30
+ TYPE_UINT => "I!",
31
+ TYPE_ULONG => "L!",
32
32
  }
33
33
 
34
34
  SIZE_MAP = {
@@ -39,16 +39,17 @@ module Fiddle
39
39
  TYPE_LONG => SIZEOF_LONG,
40
40
  TYPE_FLOAT => SIZEOF_FLOAT,
41
41
  TYPE_DOUBLE => SIZEOF_DOUBLE,
42
- -TYPE_CHAR => SIZEOF_CHAR,
43
- -TYPE_SHORT => SIZEOF_SHORT,
44
- -TYPE_INT => SIZEOF_INT,
45
- -TYPE_LONG => SIZEOF_LONG,
42
+ TYPE_UCHAR => SIZEOF_CHAR,
43
+ TYPE_USHORT => SIZEOF_SHORT,
44
+ TYPE_UINT => SIZEOF_INT,
45
+ TYPE_ULONG => SIZEOF_LONG,
46
46
  }
47
47
  if defined?(TYPE_LONG_LONG)
48
- ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG
49
- PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q"
50
- SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG
51
- PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
48
+ ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG
49
+ PACK_MAP[TYPE_LONG_LONG] = "q"
50
+ PACK_MAP[TYPE_ULONG_LONG] = "Q"
51
+ SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[TYPE_ULONG_LONG] = SIZEOF_LONG_LONG
52
+ PACK_MAP[TYPE_VOIDP] = "Q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP
52
53
  end
53
54
 
54
55
  def align(addr, align)
@@ -1,3 +1,3 @@
1
1
  module Fiddle
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
data/lib/fiddle.rb CHANGED
@@ -58,7 +58,36 @@ module Fiddle
58
58
  #
59
59
  # See Fiddle::Handle.new for more.
60
60
  def dlopen library
61
- Fiddle::Handle.new library
61
+ begin
62
+ Fiddle::Handle.new(library)
63
+ rescue DLError => error
64
+ case RUBY_PLATFORM
65
+ when /linux/
66
+ case error.message
67
+ when /\A(\/.+?): (?:invalid ELF header|file too short)/
68
+ # This may be a linker script:
69
+ # https://sourceware.org/binutils/docs/ld.html#Scripts
70
+ path = $1
71
+ else
72
+ raise
73
+ end
74
+ else
75
+ raise
76
+ end
77
+
78
+ File.open(path) do |input|
79
+ input.each_line do |line|
80
+ case line
81
+ when /\A\s*(?:INPUT|GROUP)\s*\(\s*([^\s,\)]+)/
82
+ # TODO: Should we support multiple files?
83
+ return dlopen($1)
84
+ end
85
+ end
86
+ end
87
+
88
+ # Not found
89
+ raise
90
+ end
62
91
  end
63
92
  module_function :dlopen
64
93
 
@@ -67,4 +96,8 @@ module Fiddle
67
96
  RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc:
68
97
  RTLD_LAZY = Handle::RTLD_LAZY # :nodoc:
69
98
  RTLD_NOW = Handle::RTLD_NOW # :nodoc:
99
+
100
+ Fiddle::Types.constants.each do |type|
101
+ const_set "TYPE_#{type}", Fiddle::Types.const_get(type)
102
+ end
70
103
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiddle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  - SHIBATA Hiroshi
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-10-22 00:00:00.000000000 Z
12
+ date: 2022-12-08 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A libffi wrapper for Ruby.
15
15
  email:
@@ -23,15 +23,12 @@ files:
23
23
  - LICENSE.txt
24
24
  - README.md
25
25
  - Rakefile
26
- - bin/downloader.rb
27
- - bin/extlibs.rb
28
26
  - ext/fiddle/closure.c
29
27
  - ext/fiddle/closure.h
30
28
  - ext/fiddle/conversions.c
31
29
  - ext/fiddle/conversions.h
32
30
  - ext/fiddle/depend
33
31
  - ext/fiddle/extconf.rb
34
- - ext/fiddle/extlibs
35
32
  - ext/fiddle/fiddle.c
36
33
  - ext/fiddle/fiddle.h
37
34
  - ext/fiddle/function.c
@@ -61,7 +58,7 @@ licenses:
61
58
  - BSD-2-Clause
62
59
  metadata:
63
60
  msys2_mingw_dependencies: libffi
64
- post_install_message:
61
+ post_install_message:
65
62
  rdoc_options: []
66
63
  require_paths:
67
64
  - lib
@@ -76,8 +73,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
73
  - !ruby/object:Gem::Version
77
74
  version: '0'
78
75
  requirements: []
79
- rubygems_version: 3.3.0.dev
80
- signing_key:
76
+ rubygems_version: 3.4.0.dev
77
+ signing_key:
81
78
  specification_version: 4
82
79
  summary: A libffi wrapper for Ruby.
83
80
  test_files: []
data/bin/downloader.rb DELETED
@@ -1,331 +0,0 @@
1
- # Used by configure and make to download or update mirrored Ruby and GCC
2
- # files. This will use HTTPS if possible, falling back to HTTP.
3
-
4
- require 'fileutils'
5
- require 'open-uri'
6
- require 'pathname'
7
- begin
8
- require 'net/https'
9
- rescue LoadError
10
- https = 'http'
11
- else
12
- https = 'https'
13
-
14
- # open-uri of ruby 2.2.0 accept an array of PEMs as ssl_ca_cert, but old
15
- # versions are not. so, patching OpenSSL::X509::Store#add_file instead.
16
- class OpenSSL::X509::Store
17
- alias orig_add_file add_file
18
- def add_file(pems)
19
- Array(pems).each do |pem|
20
- if File.directory?(pem)
21
- add_path pem
22
- else
23
- orig_add_file pem
24
- end
25
- end
26
- end
27
- end
28
- # since open-uri internally checks ssl_ca_cert using File.directory?,
29
- # allow to accept an array.
30
- class <<File
31
- alias orig_directory? directory?
32
- def File.directory? files
33
- files.is_a?(Array) ? false : orig_directory?(files)
34
- end
35
- end
36
- end
37
-
38
- class Downloader
39
- def self.https=(https)
40
- @@https = https
41
- end
42
-
43
- def self.https?
44
- @@https == 'https'
45
- end
46
-
47
- def self.https
48
- @@https
49
- end
50
-
51
- class GNU < self
52
- def self.download(name, *rest)
53
- if https?
54
- super("https://raw.githubusercontent.com/gcc-mirror/gcc/master/#{name}", name, *rest)
55
- else
56
- super("https://repo.or.cz/official-gcc.git/blob_plain/HEAD:/#{name}", name, *rest)
57
- end
58
- end
59
- end
60
-
61
- class RubyGems < self
62
- def self.download(name, dir = nil, since = true, options = {})
63
- require 'rubygems'
64
- options = options.dup
65
- options[:ssl_ca_cert] = Dir.glob(File.expand_path("../lib/rubygems/ssl_certs/**/*.pem", File.dirname(__FILE__)))
66
- super("https://rubygems.org/downloads/#{name}", name, dir, since, options)
67
- end
68
- end
69
-
70
- Gems = RubyGems
71
-
72
- class Unicode < self
73
- def self.download(name, *rest)
74
- super("http://www.unicode.org/Public/#{name}", name, *rest)
75
- end
76
- end
77
-
78
- def self.mode_for(data)
79
- /\A#!/ =~ data ? 0755 : 0644
80
- end
81
-
82
- def self.http_options(file, since)
83
- options = {}
84
- if since
85
- case since
86
- when true
87
- since = (File.mtime(file).httpdate rescue nil)
88
- when Time
89
- since = since.httpdate
90
- end
91
- if since
92
- options['If-Modified-Since'] = since
93
- end
94
- end
95
- options['Accept-Encoding'] = '*' # to disable Net::HTTP::GenericRequest#decode_content
96
- options
97
- end
98
-
99
- # Downloader.download(url, name, [dir, [since]])
100
- #
101
- # Update a file from url if newer version is available.
102
- # Creates the file if the file doesn't yet exist; however, the
103
- # directory where the file is being created has to exist already.
104
- # The +since+ parameter can take the following values, with associated meanings:
105
- # true ::
106
- # Take the last-modified time of the current file on disk, and only download
107
- # if the server has a file that was modified later. Download unconditionally
108
- # if we don't have the file yet. Default.
109
- # +some time value+ ::
110
- # Use this time value instead of the time of modification of the file on disk.
111
- # nil ::
112
- # Only download the file if it doesn't exist yet.
113
- # false ::
114
- # always download url regardless of whether we already have a file,
115
- # and regardless of modification times. (This is essentially just a waste of
116
- # network resources, except in the case that the file we have is somehow damaged.
117
- # Please note that using this recurringly might create or be seen as a
118
- # denial of service attack.)
119
- #
120
- # Example usage:
121
- # download 'http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt',
122
- # 'UnicodeData.txt', 'enc/unicode/data'
123
- def self.download(url, name, dir = nil, since = true, options = {})
124
- options = options.dup
125
- url = URI(url)
126
- dryrun = options.delete(:dryrun)
127
- if name
128
- file = Pathname.new(under(dir, name))
129
- else
130
- name = File.basename(url.path)
131
- end
132
- cache_save = options.delete(:cache_save) {
133
- ENV["CACHE_SAVE"] != "no"
134
- }
135
- cache = cache_file(url, name, options.delete(:cache_dir))
136
- file ||= cache
137
- if since.nil? and file.exist?
138
- if $VERBOSE
139
- $stdout.puts "#{file} already exists"
140
- $stdout.flush
141
- end
142
- if cache_save
143
- save_cache(cache, file, name)
144
- end
145
- return file.to_path
146
- end
147
- if dryrun
148
- puts "Download #{url} into #{file}"
149
- return
150
- end
151
- if link_cache(cache, file, name, $VERBOSE)
152
- return file.to_path
153
- end
154
- if !https? and URI::HTTPS === url
155
- warn "*** using http instead of https ***"
156
- url.scheme = 'http'
157
- url = URI(url.to_s)
158
- end
159
- if $VERBOSE
160
- $stdout.print "downloading #{name} ... "
161
- $stdout.flush
162
- end
163
- begin
164
- data = url.read(options.merge(http_options(file, since.nil? ? true : since)))
165
- rescue OpenURI::HTTPError => http_error
166
- if http_error.message =~ /^304 / # 304 Not Modified
167
- if $VERBOSE
168
- $stdout.puts "#{name} not modified"
169
- $stdout.flush
170
- end
171
- return file.to_path
172
- end
173
- raise
174
- rescue Timeout::Error
175
- if since.nil? and file.exist?
176
- puts "Request for #{url} timed out, using old version."
177
- return file.to_path
178
- end
179
- raise
180
- rescue SocketError
181
- if since.nil? and file.exist?
182
- puts "No network connection, unable to download #{url}, using old version."
183
- return file.to_path
184
- end
185
- raise
186
- end
187
- mtime = nil
188
- dest = (cache_save && cache && !cache.exist? ? cache : file)
189
- dest.parent.mkpath
190
- dest.open("wb", 0600) do |f|
191
- f.write(data)
192
- f.chmod(mode_for(data))
193
- mtime = data.meta["last-modified"]
194
- end
195
- if mtime
196
- mtime = Time.httpdate(mtime)
197
- dest.utime(mtime, mtime)
198
- end
199
- if $VERBOSE
200
- $stdout.puts "done"
201
- $stdout.flush
202
- end
203
- if dest.eql?(cache)
204
- link_cache(cache, file, name)
205
- elsif cache_save
206
- save_cache(cache, file, name)
207
- end
208
- return file.to_path
209
- rescue => e
210
- raise "failed to download #{name}\n#{e.message}: #{url}"
211
- end
212
-
213
- def self.under(dir, name)
214
- dir ? File.join(dir, File.basename(name)) : name
215
- end
216
-
217
- def self.cache_file(url, name, cache_dir = nil)
218
- case cache_dir
219
- when false
220
- return nil
221
- when nil
222
- cache_dir = ENV['CACHE_DIR']
223
- if !cache_dir or cache_dir.empty?
224
- cache_dir = ".downloaded-cache"
225
- end
226
- end
227
- Pathname.new(cache_dir) + (name || File.basename(URI(url).path))
228
- end
229
-
230
- def self.link_cache(cache, file, name, verbose = false)
231
- return false unless cache and cache.exist?
232
- return true if cache.eql?(file)
233
- if /cygwin/ !~ RUBY_PLATFORM or /winsymlink:nativestrict/ =~ ENV['CYGWIN']
234
- begin
235
- file.make_symlink(cache.relative_path_from(file.parent))
236
- rescue SystemCallError
237
- else
238
- if verbose
239
- $stdout.puts "made symlink #{name} to #{cache}"
240
- $stdout.flush
241
- end
242
- return true
243
- end
244
- end
245
- begin
246
- file.make_link(cache)
247
- rescue SystemCallError
248
- else
249
- if verbose
250
- $stdout.puts "made link #{name} to #{cache}"
251
- $stdout.flush
252
- end
253
- return true
254
- end
255
- end
256
-
257
- def self.save_cache(cache, file, name)
258
- if cache and !cache.eql?(file) and !cache.exist?
259
- begin
260
- file.rename(cache)
261
- rescue
262
- else
263
- link_cache(cache, file, name)
264
- end
265
- end
266
- end
267
- end
268
-
269
- Downloader.https = https.freeze
270
-
271
- if $0 == __FILE__
272
- since = true
273
- options = {}
274
- until ARGV.empty?
275
- case ARGV[0]
276
- when '-d'
277
- destdir = ARGV[1]
278
- ARGV.shift
279
- when '-p'
280
- # strip directory names from the name to download, and add the
281
- # prefix instead.
282
- prefix = ARGV[1]
283
- ARGV.shift
284
- when '-e'
285
- since = nil
286
- when '-a'
287
- since = false
288
- when '-n', '--dryrun'
289
- options[:dryrun] = true
290
- when '--cache-dir'
291
- options[:cache_dir] = ARGV[1]
292
- ARGV.shift
293
- when /\A--cache-dir=(.*)/m
294
- options[:cache_dir] = $1
295
- when /\A-/
296
- abort "#{$0}: unknown option #{ARGV[0]}"
297
- else
298
- break
299
- end
300
- ARGV.shift
301
- end
302
- dl = Downloader.constants.find do |name|
303
- ARGV[0].casecmp(name.to_s) == 0
304
- end unless ARGV.empty?
305
- $VERBOSE = true
306
- if dl
307
- dl = Downloader.const_get(dl)
308
- ARGV.shift
309
- ARGV.each do |name|
310
- dir = destdir
311
- if prefix
312
- name = name.sub(/\A\.\//, '')
313
- if name.start_with?(destdir+"/")
314
- name = name[(destdir.size+1)..-1]
315
- if (dir = File.dirname(name)) == '.'
316
- dir = destdir
317
- else
318
- dir = File.join(destdir, dir)
319
- end
320
- else
321
- name = File.basename(name)
322
- end
323
- name = "#{prefix}/#{name}"
324
- end
325
- dl.download(name, dir, since, options)
326
- end
327
- else
328
- abort "usage: #{$0} url name" unless ARGV.size == 2
329
- Downloader.download(ARGV[0], ARGV[1], destdir, since, options)
330
- end
331
- end