lib/ffi-tk/ffi/tcl/eval_result.rb in ffi-tk-2010.03 vs lib/ffi-tk/ffi/tcl/eval_result.rb in ffi-tk-2010.06

- old
+ new

@@ -7,23 +7,26 @@ def self.reset_types(interp) TYPES.clear list = Tcl.new_list_obj(0, nil) Tcl.append_all_obj_types(interp, list) - result_pointer = MemoryPointer.new(:pointer) - count_pointer = MemoryPointer.new(:int) - length_pointer = MemoryPointer.new(:int) + objc_ptr = MemoryPointer.new(:int) + objv_ptr = MemoryPointer.new(:pointer) - Tcl.list_obj_length(interp, list, count_pointer) - count = count_pointer.get_int(0) + string_length_ptr = MemoryPointer.new(:int) - (0...count).each do |idx| - Tcl.list_obj_index(interp, list, idx, result_pointer) - element_pointer = result_pointer.get_pointer(0) - name = Tcl.get_string_from_obj(element_pointer, length_pointer) - type = Tcl.get_obj_type(name) - TYPES[type.to_i] = name.to_sym + if Tcl.list_obj_get_elements(interp, list, objc_ptr, objv_ptr) == 0 + 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) + type = Tcl.get_obj_type(name) + TYPES[type.to_i] = name.to_sym + end + else + panic 'Tcl_ListObjGetElements' end end def self.guess(interp, obj, fallback = nil) obj = Obj.new(obj) unless obj.respond_to?(:type) @@ -63,39 +66,57 @@ value = guess(interp, pointer, :to_string) block_given? ? yield(value) : value end end - def self.map_list_core(interp, obj) - result_pointer = MemoryPointer.new(:pointer) - count_pointer = MemoryPointer.new(:int) - length_pointer = MemoryPointer.new(:int) + def self.map_list_core(interp, obj, &block) + objc_ptr = MemoryPointer.new(:int) + objv_ptr = MemoryPointer.new(:pointer) - Tcl.list_obj_length(interp, obj, count_pointer) - count = count_pointer.get_int(0) - - (0...count).map do |idx| - Tcl.list_obj_index(interp, obj, idx, result_pointer) - yield result_pointer.get_pointer(0) + 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) + else + panic(interp, 'Tcl_ListObjGetElements') end end def self.to_boolean(interp, obj) boolean_pointer = MemoryPointer.new(:int) - Tcl.get_boolean_from_obj(interp, obj, boolean_pointer) - boolean_pointer.get_int(0) == 1 + + if Tcl.get_boolean_from_obj(interp, obj, boolean_pointer) == 0 + boolean_pointer.get_int(0) == 1 + else + panic(interp, 'Tcl_GetBooleanFromObj') + end end def self.to_int(interp, obj) int_pointer = MemoryPointer.new(:int) - Tcl.get_int_from_obj(interp, obj, int_pointer) - int_pointer.get_int(0) + + if 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) length_pointer = MemoryPointer.new(:int) + string = Tcl.get_string_from_obj(obj, length_pointer) string.force_encoding(Encoding.default_external) + end + + def self.panic(interp, function) + message = guess(interp, Obj.new(Tcl.get_obj_result(interp))).to_s + + if message.empty? + raise 'Failure during call of: %p' % [function] + else + raise '%s during call of: %p' % [message, function] + end end def to_a(&block) self.class.to_list(interp, obj, &block) end