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|