From 80c11812e1e1c3c33158cd25eb0db0dba1ced4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Mon, 25 Apr 2011 20:38:14 +0200 Subject: ecore_getopt : prevent FFI::MemoryPointer.from_string beeing GC'ed --- lib/efl/ecore_getopt.rb | 22 +++++++--- spec/ecore_getopt_spec.rb | 101 +++++++++++++++++++++++----------------------- 2 files changed, 67 insertions(+), 56 deletions(-) diff --git a/lib/efl/ecore_getopt.rb b/lib/efl/ecore_getopt.rb index 00de244..10074b5 100644 --- a/lib/efl/ecore_getopt.rb +++ b/lib/efl/ecore_getopt.rb @@ -92,6 +92,13 @@ module Efl @values = [ [ :ptrp, FFI::Pointer::NULL ] ] + @refs = [] # to prevent FFI::MemoryPointer.from_string from beeing GC'ed + end + def p_from_string r + return r if r==FFI::Pointer::NULL + p = FFI::MemoryPointer.from_string r + @refs << p + p end def << o @options.insert -2, o @@ -99,6 +106,9 @@ module Efl def value type, ptr @values.insert -2, [ type, ptr ] end + def to_ptr + @parser_p.to_ptr + end def create @parser_p = Efl::API::EcoreGetopt.new FFI::MemoryPointer.new (Efl::API::EcoreGetopt.size+Efl::API::EcoreGetoptDesc.size*@options.length), 1 [:prog,:usage,:version,:copyright,:license,:description].each do |sym| @@ -108,8 +118,8 @@ module Efl @options.each_with_index do |o,i| d = @parser_p.desc_ptr i d[:shortname] = o[0].ord - d[:longname] = (o[1]==FFI::Pointer::NULL ? FFI::Pointer::NULL : FFI::MemoryPointer.from_string(o[1])) - d[:help] = (o[2]==FFI::Pointer::NULL ? FFI::Pointer::NULL : FFI::MemoryPointer.from_string(o[2])) + d[:longname] = p_from_string o[1] + d[:help] = p_from_string o[2] d[:metavar] = o[3] d[:action] = o[4] k, v = o[5] @@ -128,7 +138,7 @@ module Efl st[:arg_req] = v[1] if not v[2].nil? if v[2][0]==:strv - st[:def][:strv] = FFI::MemoryPointer.from_string v[2][1] + st[:def][:strv] = p_from_string v[2][1] else st[:def][v[2][0]] = v[2][1] end @@ -151,7 +161,7 @@ module Efl def parse argv ptr = FFI::MemoryPointer.new(:pointer, argv.length+1) argv.each_with_index do |s, i| - ptr[i].put_pointer 0, FFI::MemoryPointer.from_string(s) + ptr[i].put_pointer 0, p_from_string(s) end ptr[argv.length].put_pointer 0, FFI::Pointer::NULL Efl::EcoreGetopt.parse @parser_p, @values_p, argv.length, ptr @@ -192,7 +202,7 @@ module Efl def choice short, long, help, choices ptr = FFI::MemoryPointer.new(:pointer, choices.length+1) choices.each_with_index do |s, i| - ptr[i].put_pointer 0, FFI::MemoryPointer.from_string(s) + ptr[i].put_pointer 0, p_from_string(s) end ptr[choices.length].put_pointer 0, FFI::Pointer::NULL self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_choice, [:choices,ptr] ] @@ -200,7 +210,7 @@ module Efl def choice_metavar short, long, help, meta, choices ptr = FFI::MemoryPointer.new(:pointer, choices.length+1) choices.each_with_index do |s, i| - ptr[i].put_pointer 0, FFI::MemoryPointer.from_string(s) + ptr[i].put_pointer 0, p_from_string(s) end ptr[choices.length].put_pointer 0, FFI::Pointer::NULL self << [ short, long, help, meta, :ecore_getopt_action_choice, [:choices,ptr] ] diff --git a/spec/ecore_getopt_spec.rb b/spec/ecore_getopt_spec.rb index 87c4c33..6f5c7f0 100644 --- a/spec/ecore_getopt_spec.rb +++ b/spec/ecore_getopt_spec.rb @@ -11,6 +11,7 @@ describe Efl::EcoreGetopt do # @p = Efl::EcoreGetopt::Parser.new :prog =>"Prog", :usage => "Usage", :version => "0.0.0", :copyright => "less", :license => "MIT", :description => "description", :strict => 1 @callback = Proc.new do |parser, desc, string, data, value| + parser.address.should eql @p.to_ptr.address string.should eql "my_data" data.read_string.should eql "cb_data" value.read_pointer.read_int.should eql 99 @@ -222,54 +223,54 @@ describe Efl::EcoreGetopt do args = @p.parse ["progname","-bmy_data"] end end -# describe "simple long options" do -# it "should handle --int" do -# @values[:int].read_int.should eql 0 -# args = @p.parse ["progname","--int=666"] -# @values[:int].read_int.should eql 666 -# end -# it "should handle --double" do -# @values[:double].read_double.should eql 3.1415926 -# args = @p.parse ["progname","--double=6.66"] -# @values[:double].read_double.should eql 6.66 -# end -# it "should handle --short" do -# @values[:short].read_short.should eql 9 -# args = @p.parse ["progname","--short=125"] -# @values[:short].read_short.should eql 125 -# end -# it "should handle --long" do -# @values[:long].read_long.should eql 666 -# args = @p.parse ["progname","--long=69"] -# @values[:long].read_long.should eql 69 -# end -# it "should handle --const" do -# @values[:const].read_int.should eql -666 -# args = @p.parse ["progname","--const"] -# @values[:const].read_int.should eql 123456 -# end -# it "should handle --true" do -# @values[:false].read_uchar.should eql 0 -# args = @p.parse ["progname","--true"] -# @values[:false].read_uchar.should eql 1 -# end -# it "should handle --false" do -# @values[:true].read_uchar.should eql 1 -# args = @p.parse ["progname","--false"] -# @values[:true].read_uchar.should eql 0 -# end -# it "should handle --many" do -# @values[:choice].read_pointer.should eql FFI::Pointer::NULL -# args = @p.parse ["progname","--many=ch3"] -# @values[:choice].read_pointer.read_string.should eql "ch3" -# end -# it "should handle --count" do -# @values[:count].read_int.should eql 664 -# args = @p.parse ["progname","--count","--count"] -# @values[:count].read_int.should eql 666 -# end -# it "should handle --callback" do -# args = @p.parse ["progname","--callback=my_data"] -# end -# end + describe "simple long options" do + it "should handle --int" do + @values[:int].read_int.should eql 0 + args = @p.parse ["progname","--int=666"] + @values[:int].read_int.should eql 666 + end + it "should handle --double" do + @values[:double].read_double.should eql 3.1415926 + args = @p.parse ["progname","--double=6.66"] + @values[:double].read_double.should eql 6.66 + end + it "should handle --short" do + @values[:short].read_short.should eql 9 + args = @p.parse ["progname","--short=125"] + @values[:short].read_short.should eql 125 + end + it "should handle --long" do + @values[:long].read_long.should eql 666 + args = @p.parse ["progname","--long=69"] + @values[:long].read_long.should eql 69 + end + it "should handle --const" do + @values[:const].read_int.should eql -666 + args = @p.parse ["progname","--const"] + @values[:const].read_int.should eql 123456 + end + it "should handle --true" do + @values[:false].read_uchar.should eql 0 + args = @p.parse ["progname","--true"] + @values[:false].read_uchar.should eql 1 + end + it "should handle --false" do + @values[:true].read_uchar.should eql 1 + args = @p.parse ["progname","--false"] + @values[:true].read_uchar.should eql 0 + end + it "should handle --many" do + @values[:choice].read_pointer.should eql FFI::Pointer::NULL + args = @p.parse ["progname","--many=ch3"] + @values[:choice].read_pointer.read_string.should eql "ch3" + end + it "should handle --count" do + @values[:count].read_int.should eql 664 + args = @p.parse ["progname","--count","--count"] + @values[:count].read_int.should eql 666 + end + it "should handle --callback" do + args = @p.parse ["progname","--callback=my_data"] + end + end end -- cgit v1.1-2-g2b99