class Argument def description @func.param_desc[@name] || if @prop[:param] "@param [#{rb_class}] #{@name}" elsif @prop[:narray] "@param [#{na_class}] #{@name}" end end NUM2DATA = { "double"=>"%2 = NUM2DBL(%1)", "int"=>"%2 = NUM2INT(%1)", "unsigned int"=>"%2 = NUM2UINT(%1)", "size_t"=>"%2 = NUM2SIZET(%1)", "gsl_mode_t"=>"%2 = NUM2INT(%1)", "gsl_sf_legendre_t"=>"%2 = NUM2INT(%1)", "gsl_sf_mathieu_workspace *"=>' if (rb_obj_is_kind_of(%1,cWorkspace)!=Qtrue) { rb_raise(rb_eTypeError,"last argument must be " "Numo::GSL::Sf::MathieuWorkspace class"); } TypedData_Get_Struct(%1, gsl_sf_mathieu_workspace, &mathieuws_type, %2)' } DATA2NUM = { "double"=>"DBL2NUM(%1)", "int"=>"INT2NUM(%1)", "unsigned int"=>"UINT2NUM(%1)", "size_t"=>"SIZET2NUM(%1)", "gsl_sf_result *"=>["DBL2NUM(%1.val)","DBL2NUM(%1.err)"] } TYPEMAP = { "double"=>"cDF", "gsl_complex"=>"cDC", "unsigned int"=>"cUI", "int"=>"cI", "size_t"=>"cSZ", } NACLASSMAP = { "double"=>"Numo::DFloat", "gsl_complex"=>"Numo::DComplex", "unsigned int"=>"Numo::UInt", "int"=>"Numo::Int", "size_t"=>"Numo::UInt64", "gsl_sf_result *"=>["Numo::DFloat"]*2, "gsl_sf_result_e10 *"=>["Numo::DFloat"]*2+["Numo::Int"], "gsl_sf_mathieu_workspace *"=>"Numo::GSL::Sf::MathieuWorkspace" } RBCLASSMAP = { "double"=>"Float", "gsl_complex"=>"Complex", "unsigned int"=>"Integer", "int"=>"Integer", "size_t"=>"Integer", "gsl_mode_t"=>"Integer", "gsl_sf_result *"=>["Float"]*2 } CTYPEMAP = { "double"=>"double", #"unsigned int"=>"uint32_t", #"int"=>"int32_t", "unsigned int"=>"unsigned int", "int"=>"int", "size_t"=>"uint64_t", "gsl_complex"=>"gsl_complex", } RETNAMEMAP = { "double"=>"Numo::DFloat", "gsl_complex"=>"Numo::DComplex", #"unsigned int"=>"Numo::UInt32", #"int"=>"Numo::Int32", "unsigned int"=>"Numo::UInt", "int"=>"Numo::Int", "size_t"=>"Numo::UInt64", "gsl_sf_result *"=>["Numo::DFloat"]*2, "gsl_sf_result_e10 *"=>["Numo::DFloat"]*2+["Numo::Int"] } def initialize(func,idx,type,name,prop) @func = func @idx = idx @type = type @name = name @prop = prop @pass = @prop[:pass] if /(.+)\*$/ =~ @type @type2 = $1.strip end if @prop[:output] @n_out = case @type when "gsl_sf_result_e10 *"; 3 when "gsl_sf_result *"; 2 else 1 end end @ctype = CTYPEMAP[@type] || CTYPEMAP[@type2] end attr_reader :type, :name attr_reader :pass, :n_out [:input,:output,:param,:narray].each do |sym| define_method(sym){@prop[sym]} end def c_var "c#{@idx}" end def c_arg (@pass == :pointer) ? "&"+c_var : c_var end def v_var if @func.n_arg < 0 "v[#{@idx}]" else "v#{@idx}" end end def ain_def "{#{na_type},0}" end def aout_def case @type when "gsl_sf_result_e10 *" return "{cDF,0},{cDF,0},{cI,0}" when "gsl_sf_result *" return "{cDF,0},{cDF,0}" end case @pass when :array "{#{na_type},1,shape}" when :pointer,:return "{#{na_type},0}" else raise "no aout_def for #{self.inspect}" end end def na_type TYPEMAP[@type] || TYPEMAP[@type2] end def na_class NACLASSMAP[@type] || NACLASSMAP[@type2] end def rb_class RBCLASSMAP[@type] || RBCLASSMAP[@type2] end def ret_val case @type when "gsl_sf_result *" [@name+".val",@name+".err"] when "gsl_sf_result_e10 *" [@name+".val",@name+".err",@name+".e10"] else @name end end def def_var if @prop[:param] "#{@type} #{c_var};" elsif @prop[:input] "#{@type} #{c_var};" elsif @pass == :array "#{@type} *#{c_var};" elsif @pass == :pointer "#{@type2} #{c_var};" elsif @pass == :return "#{@type} #{c_var};" else raise "no variable definition" end end def def_value "VALUE #{v_var};" end def set_value NUM2DATA[@type].gsub(/%1/,v_var).sub(/%2/,c_var)+";" end def get_value case a = DATA2NUM[@type] when String a.gsub(/%1/,c_var) when Array a.map{|s| s.gsub(/%1/,c_var)} end end def store_to_array(va) a = get_value a = [a] unless Array === a a.map{|x|"rb_ary_push(#{va},#{x});"}.join("\n"+" "*8) end def set_param(opt) n = @func.n_input if @type == "gsl_mode_t" && n == @idx+1 return < 1 r = "@return [[#{t}]] array of [#{v}]" else r = "@return [#{t}] #{v}" end @args_input.map{|a| a.description}+[r] end def desc_param_scalar #t = (["Numo::DFloat"]*n_out).join(",") t = @args_out.map{|a| a.rb_class}.flatten.join(", ") v = @args_out.map{|a| a.ret_val}.flatten.join(", ") if n_out > 1 r = "@return [[#{t}]] array of [#{v}]" else r = "@return [#{t}] #{v}" end @args_input.map{|a| a.description}+[r] end end