lib/ffi-tk/ffi/tcl/eval_result.rb in ffi-tk-2010.08.23 vs lib/ffi-tk/ffi/tcl/eval_result.rb in ffi-tk-2018.02.20

- old
+ new

@@ -1,5 +1,6 @@ +# frozen_string_literal: true module FFI module Tcl # This whole class feels very awkward, maybe it should be merged with Obj. class EvalResult < ::Struct.new(:interp, :obj) TYPES = {} @@ -13,10 +14,11 @@ objv_ptr = MemoryPointer.new(:pointer) string_length_ptr = MemoryPointer.new(:int) if Tcl.list_obj_get_elements(interp, list, objc_ptr, objv_ptr) == 0 + return [] if objv_ptr.get_pointer(0).null? array_ptr = objv_ptr.get_pointer(0) array_length = objc_ptr.get_int(0) array = array_ptr.read_array_of_pointer(array_length) array.each do |type_ptr| name = Tcl.get_string_from_obj(type_ptr, string_length_ptr) @@ -28,10 +30,11 @@ end end def self.guess(interp, obj, fallback = nil) obj = Obj.new(obj) unless obj.respond_to?(:type) + # p obj: obj, obj_type: obj.type type = TYPES[obj.type.to_i] case type when :list to_list(interp, obj) @@ -39,20 +42,53 @@ to_string(interp, obj) when :int to_int(interp, obj) when :double to_double(interp, obj) + when :dict + to_dict(interp, obj) + when :window + to_window(interp, obj) else if fallback __send__(fallback, interp, obj) + elsif type.nil? && obj.bytes == '' + nil + elsif type.nil? + to_string(interp, obj) else - raise "Unknown type: %p" % [type] if type - new(interp, obj) + raise 'Unknown type: %p' % [type] end end end + def self.to_window(interp, obj) + p interp: interp, obj: obj + end + + def self.to_dict(interp, obj) + out = {} + + search = MemoryPointer.new(:pointer) + done = MemoryPointer.new(:int) + key_ptr = MemoryPointer.new(:pointer) + value_ptr = MemoryPointer.new(:pointer) + strlen = MemoryPointer.new(:int) + + Tcl.dict_obj_first(interp, obj, search, key_ptr, value_ptr, done) + + while done.get_int(0) != 1 + key = Tcl.get_string_from_obj(key_ptr.get_pointer(0), strlen) + value = Tcl.get_string_from_obj(value_ptr.get_pointer(0), strlen) + out[key] = value + + Tcl.dict_obj_next(search, key_ptr, value_ptr, done) + end + + out + end + def self.to_double(interp, obj) double_pointer = MemoryPointer.new(:double) if Tcl.get_double_from_obj(interp, obj, double_pointer) == 0 double_pointer.get_double(0) @@ -71,13 +107,14 @@ def self.map_list_core(interp, obj, &block) objc_ptr = MemoryPointer.new(:int) objv_ptr = MemoryPointer.new(:pointer) if Tcl.list_obj_get_elements(interp, obj, objc_ptr, objv_ptr) == 0 - objv_ptr.get_pointer(0). - read_array_of_pointer(objc_ptr.get_int(0)). - map(&block) + return [] if objv_ptr.get_pointer(0).null? + objv_ptr.get_pointer(0) + .read_array_of_pointer(objc_ptr.get_int(0)) + .map(&block) else panic(interp, 'Tcl_ListObjGetElements') end end @@ -92,18 +129,20 @@ end def self.to_int(interp, obj) int_pointer = MemoryPointer.new(:int) - if Tcl.get_int_from_obj(interp, obj, int_pointer) == 0 + if obj.bytes == '' + '' # used by text widget -endline + elsif Tcl.get_int_from_obj(interp, obj, int_pointer) == 0 int_pointer.get_int(0) else panic(interp, 'Tcl_GetIntFromObj') end end - def self.to_string(interp, obj) + def self.to_string(_interp, obj) length_pointer = MemoryPointer.new(:int) string = Tcl.get_string_from_obj(obj, length_pointer) string.force_encoding(Encoding.default_external) end @@ -160,10 +199,10 @@ def to_tcl to_s.to_tcl end def inspect - "#<EvalResult #{to_s}>" + "#<EvalResult #{self}>" end end end end