diff options
Diffstat (limited to 'lib/reline/terminfo.rb')
-rw-r--r-- | lib/reline/terminfo.rb | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/lib/reline/terminfo.rb b/lib/reline/terminfo.rb index b4d1d735f8..6885a0c6be 100644 --- a/lib/reline/terminfo.rb +++ b/lib/reline/terminfo.rb @@ -31,21 +31,7 @@ module Reline::Terminfo @curses_dl = false def self.curses_dl 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. - 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 + if Fiddle.const_defined?(:TYPE_VARIADIC) curses_dl_files.each do |curses_name| result = Fiddle::Handle.new(curses_name) rescue Fiddle::DLError @@ -74,28 +60,31 @@ module Reline::Terminfo #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) + begin + #extern 'int tigetflag(char *str)' + @tigetflag = Fiddle::Function.new(curses_dl['tigetflag'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT) + rescue Fiddle::DLError + # OpenBSD lacks tigetflag + #extern 'int tgetflag(char *str)' + @tigetflag = Fiddle::Function.new(curses_dl['tgetflag'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT) + end + begin + #extern 'int tigetnum(char *str)' + @tigetnum = Fiddle::Function.new(curses_dl['tigetnum'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT) + rescue Fiddle::DLError + # OpenBSD lacks tigetnum + #extern 'int tgetnum(char *str)' + @tigetnum = Fiddle::Function.new(curses_dl['tgetnum'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT) + end def self.setupterm(term, fildes) - errret_int = String.new("\x00" * 8, encoding: 'ASCII-8BIT') + errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT) ret = @setupterm.(term, fildes, errret_int) - errret = errret_int.unpack1('i') case ret when 0 # OK - 0 + @term_supported = true when -1 # ERR - case errret - when 1 - raise TerminfoError.new('The terminal is hardcopy, cannot be used for curses applications.') - when 0 - raise TerminfoError.new('The terminal could not be found, or that it is a generic type, having too little information for curses applications to run.') - when -1 - raise TerminfoError.new('The terminfo database could not be found.') - else # unknown - -1 - end - else # unknown - -2 + @term_supported = false end end @@ -106,6 +95,7 @@ module Reline::Terminfo end def self.tigetstr(capname) + raise TerminfoError, "capname is not String: #{capname.inspect}" unless capname.is_a?(String) capability = @tigetstr.(capname) case capability.to_i when 0, -1 @@ -122,9 +112,38 @@ module Reline::Terminfo @tiparm.(str, *new_args).to_s end + def self.tigetflag(capname) + raise TerminfoError, "capname is not String: #{capname.inspect}" unless capname.is_a?(String) + flag = @tigetflag.(capname).to_i + case flag + when -1 + raise TerminfoError, "not boolean capability: #{capname}" + when 0 + raise TerminfoError, "can't find capability: #{capname}" + end + flag + end + + def self.tigetnum(capname) + raise TerminfoError, "capname is not String: #{capname.inspect}" unless capname.is_a?(String) + num = @tigetnum.(capname).to_i + case num + when -2 + raise TerminfoError, "not numeric capability: #{capname}" + when -1 + raise TerminfoError, "can't find capability: #{capname}" + end + num + end + + # NOTE: This means Fiddle and curses are enabled. def self.enabled? true end + + def self.term_supported? + @term_supported + end end if Reline::Terminfo.curses_dl module Reline::Terminfo |