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