lib/reline/terminfo.rb in reline-0.2.6 vs lib/reline/terminfo.rb in reline-0.2.7
- old
+ new
@@ -4,36 +4,71 @@
module Reline::Terminfo
extend Fiddle::Importer
class TerminfoError < StandardError; end
- @curses_dl = nil
+ def self.curses_dl_files
+ case RUBY_PLATFORM
+ when /mingw/, /mswin/
+ # aren't supported
+ []
+ when /cygwin/
+ %w[cygncursesw-10.dll cygncurses-10.dll]
+ when /darwin/
+ %w[libncursesw.dylib libcursesw.dylib libncurses.dylib libcurses.dylib]
+ else
+ %w[libncursesw.so libcursesw.so libncurses.so libcurses.so]
+ end
+ end
+
+ @curses_dl = false
def self.curses_dl
- return @curses_dl if @curses_dl
- if Fiddle.const_defined?(:VERSION) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
+ return @curses_dl unless @curses_dl == false
+ if RUBY_VERSION >= '3.0.0'
+ # Gem module isn't defined in test-all of the Ruby repository, and
+ # Fiddle in Ruby 3.0.0 or later supports Fiddle::TYPE_VARIADIC.
+ fiddle_supports_variadic = true
+ elsif Fiddle.const_defined?(:VERSION) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
# Fiddle::TYPE_VARIADIC is supported from Fiddle 1.0.1.
- %w[libncursesw.so libcursesw.so libncurses.so libcurses.so].each do |curses_name|
+ fiddle_supports_variadic = true
+ else
+ fiddle_supports_variadic = false
+ end
+ if fiddle_supports_variadic and not Fiddle.const_defined?(:TYPE_VARIADIC)
+ # If the libffi version is not 3.0.5 or higher, there isn't TYPE_VARIADIC.
+ fiddle_supports_variadic = false
+ end
+ if fiddle_supports_variadic
+ curses_dl_files.each do |curses_name|
result = Fiddle::Handle.new(curses_name)
rescue Fiddle::DLError
next
else
@curses_dl = result
break
end
end
+ @curses_dl = nil if @curses_dl == false
@curses_dl
end
end
module Reline::Terminfo
dlload curses_dl
#extern 'int setupterm(char *term, int fildes, int *errret)'
@setupterm = Fiddle::Function.new(curses_dl['setupterm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
#extern 'char *tigetstr(char *capname)'
@tigetstr = Fiddle::Function.new(curses_dl['tigetstr'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOIDP)
- #extern 'char *tiparm(const char *str, ...)'
- @tiparm = Fiddle::Function.new(curses_dl['tiparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
+ begin
+ #extern 'char *tiparm(const char *str, ...)'
+ @tiparm = Fiddle::Function.new(curses_dl['tiparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
+ rescue Fiddle::DLError
+ # OpenBSD lacks tiparm
+ #extern 'char *tparm(const char *str, ...)'
+ @tiparm = Fiddle::Function.new(curses_dl['tparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
+ end
+ # TODO: add int tigetflag(char *capname) and int tigetnum(char *capname)
def self.setupterm(term, fildes)
errret_int = String.new("\x00" * 8, encoding: 'ASCII-8BIT')
ret = @setupterm.(term, fildes, errret_int)
errret = errret_int.unpack('i')[0]
@@ -54,15 +89,22 @@
else # unknown
-2
end
end
- def self.tigetstr(capname)
- result = @tigetstr.(capname).to_s
- def result.tiparm(*args) # for method chain
+ class StringWithTiparm < String
+ def tiparm(*args) # for method chain
Reline::Terminfo.tiparm(self, *args)
end
- result
+ end
+
+ def self.tigetstr(capname)
+ capability = @tigetstr.(capname)
+ case capability.to_i
+ when 0, -1
+ raise TerminfoError, "can't find capability: #{capname}"
+ end
+ StringWithTiparm.new(capability.to_s)
end
def self.tiparm(str, *args)
new_args = []
args.each do |a|