Skip to content

Commit

Permalink
Change LibraryPath.new to keyword arguments and add documentation
Browse files Browse the repository at this point in the history
Because abi_number and root aren't self descriptive.
  • Loading branch information
larskanis committed Sep 15, 2023
1 parent 6a1d5a2 commit b53f39d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
6 changes: 3 additions & 3 deletions lib/ffi/library.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
module FFI
CURRENT_PROCESS = USE_THIS_PROCESS_AS_LIBRARY = FFI.make_shareable(Object.new)

# @param [#to_s] lib library name
# @param [String, FFI::LibraryPath] lib library name or LibraryPath object
# @return [String] library name formatted for current platform
# Transform a generic library name to a platform library name
# @example
Expand All @@ -43,9 +43,9 @@ module FFI
# # Windows
# FFI.map_library_name 'c' # -> "msvcrt.dll"
# FFI.map_library_name 'jpeg' # -> "jpeg.dll"
def self.map_library_name(value)
def self.map_library_name(lib)
# Mangle the library name to reflect the native library naming conventions
LibraryPath.wrap(value).to_s
LibraryPath.wrap(lib).to_s
end

# Exception raised when a function is not found in libraries
Expand Down
35 changes: 32 additions & 3 deletions lib/ffi/library_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,36 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#

module FFI
class LibraryPath < ::Struct.new(:name, :abi_number, :root)
# Transform a generic library name and ABI number to a platform library name
#
# Example:
# module LibVips
# extend FFI::Library
# ffi_lib LibraryPath.new("vips", abi_number: 42)
# end
#
# This translates to the following library file names:
# libvips-42.dll on Windows
# libvips.so.42 on Linux
# libvips.42.dylib on Macos
#
# See https://packaging.ubuntu.com/html/libraries.html for more information about library naming.
class LibraryPath
attr_reader :name
attr_reader :abi_number
attr_reader :root

# Build a new library path
#
# * <tt>name</tt> : The name of the library without file prefix or suffix.
# * <tt>abi_number</tt> : The ABI number of the library.
# * <tt>root</tt> : An optional base path prepended to the library name.
def initialize(name, abi_number: nil, root: nil)
@name = name
@abi_number = abi_number
@root = root
end

def self.wrap(value)
# We allow instances of LibraryPath to pass through transparently:
return value if value.is_a?(self)
Expand Down Expand Up @@ -57,12 +86,12 @@ def full_name
"#{Platform::LIBPREFIX}#{name}.#{Platform::LIBSUFFIX}.#{abi_number}"
end
else
# Otherwise we just use a generic format:
# Otherwise we just add prefix and suffix:
lib = name
# Add library prefix if missing
lib = Platform::LIBPREFIX + lib unless lib =~ /^#{Platform::LIBPREFIX}/
# Add library extension if missing
r = Platform::IS_WINDOWS || Platform::IS_MAC ? "\\.#{Platform::LIBSUFFIX}$" : "\\.so($|\\.[1234567890]+)"
r = Platform.windows? || Platform.mac? ? "\\.#{Platform::LIBSUFFIX}$" : "\\.so($|\\.[1234567890]+)"
lib += ".#{Platform::LIBSUFFIX}" unless lib =~ /#{r}/
lib
end
Expand Down
4 changes: 2 additions & 2 deletions spec/ffi/ffi_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
end

it "should return library path with abi version" do
expect(FFI.map_library_name(FFI::LibraryPath.new('vips', 42))).to be =~ /#{prefix}vips.*42/
expect(FFI.map_library_name(FFI::LibraryPath.new('vips', abi_number: 42))).to be =~ /#{prefix}vips.*42/
end

it "should return library path with root" do
root = "/non/existant/root"

expect(FFI.map_library_name(FFI::LibraryPath.new('vips', 42, root))).to be =~ /#{root}/#{prefix}vips.*42/
expect(FFI.map_library_name(FFI::LibraryPath.new('vips', abi_number: 42, root: root))).to be =~ /#{root}/#{prefix}vips.*42/
end
end

Expand Down

0 comments on commit b53f39d

Please sign in to comment.