Extended maintenance of Ruby versions 1.8.7 and 1.9.2 ended on July 31, 2014. Read more

In Files

  • dl/install.rb
  • dl/mkcall.rb
  • dl/mkcallback.rb
  • dl/mkcbtable.rb
  • dl/type.rb

Object

Constants

DLTYPE

example:

DLTYPE[INT][:rb2c]["arg0"] => "NUM2INT(arg0)"
DLTYPE[DOUBLE][:c2rb]["r"] => "rb_float_new(r)"
SO_LIBS

Public Instance Methods

find(dir, match = /./) click to toggle source
 
               # File dl/install.rb, line 13
def find(dir, match = /./)
  Dir.chdir(dir)
  files = []
  Dir.new(".").each{|file|
    if( file != "." && file != ".." )
      case File.ftype(file)
      when "file"
        if( file =~ match )
          files.push(File.join(dir,file))
        end
      when "directory"
        files += find(file, match).collect{|f| File.join(dir,f)}
      end
    end
  }
  Dir.chdir("..")
  return files
end
            
install() click to toggle source
 
               # File dl/install.rb, line 32
def install()
  rb_files = find(File.join(".","lib"), /.rb$/)

  SO_LIBS.each{|f|
    File.makedirs($rubylibdir, "#{$archdir}")
    File.install(f, File.join($archdir,f), 0555, true)
  }

  rb_files.each{|f|
    origfile = f
    instfile = File.join($rubylibdir, origfile.sub("./lib/",""))
    instdir  = File.dirname(instfile)
    File.makedirs(instdir)
    File.install(origfile, instfile, 0644, true)
  }
end
            
mkfunc(rettype, fnum, argc) click to toggle source
 
               # File dl/mkcallback.rb, line 7
def mkfunc(rettype, fnum, argc)
  args = (0..(argc-1)).collect{|i| "long arg#{i}"}.join(", ")

  subst_code = (0..(argc-1)).collect{|i|
    "  buff[#{i.to_s}] = arg#{i.to_s};"
  }.join("\n")

  ret_code =
    if( DLTYPE[rettype][:c2rb] )
      "  return #{DLTYPE[rettype][:rb2c]['retval']};"
    else
      "  /* no return value */"
    end

  code = [
    "static #{DLTYPE[rettype][:ctype]}",
    "rb_dl_callback_func_#{rettype.to_s}_#{fnum.to_s}(#{args})",
    "{",
    "  VALUE retval, proto, proc, obj;",
    "  VALUE argv[#{argc.to_s}];",
    "  int  argc;",
    "  long buff[#{argc.to_s}];",
    "",
    subst_code,
    "",
    "  obj = rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(#{rettype.to_s}),INT2NUM(#{fnum.to_s})));",
    "  if(NIL_P(obj))",
    "    rb_raise(rb_eDLError, \"callback function does not exist in DL::FuncTable\");",
    "  Check_Type(obj, T_ARRAY);",
    "  proto = rb_ary_entry(obj, 0);",
    "  proc  = rb_ary_entry(obj, 1);",
    "  Check_Type(proto, T_STRING);",
    "  if( RSTRING(proto)->len >= #{argc.to_s} )",
    "    rb_raise(rb_eArgError, \"too many arguments\");",
    "  rb_dl_scan_callback_args(buff, RSTRING(proto)->ptr, &argc, argv);",
    "  retval = rb_funcall2(proc, id_call, argc, argv);",
    "",
    ret_code,
    "}",
  ].join("\n")

  return code
end
            
mktable(rettype, fnum, argc) click to toggle source
 
               # File dl/mkcbtable.rb, line 7
def mktable(rettype, fnum, argc)
  code =
    "rb_dl_callback_table[#{rettype}][#{fnum}] = &rb_dl_callback_func_#{rettype.to_s}_#{fnum};"
  return code
end
            
num2types(num) click to toggle source
 
               # File dl/type.rb, line 97
def num2types(num)
  ts = []
  i  = 0
  t = tget(num,i)
  while( (t != VOID && i > 0) || (i == 0) )
    ts.push(DLTYPE[t][:ctype])
    i += 1
    t = tget(num,i)
  end
  ts
end
            
output_arg(x,i) click to toggle source
 
               # File dl/mkcall.rb, line 7
def output_arg(x,i)
  "args[#{i}].#{DLTYPE[x][:stmem]}"
end
            
output_args(types) click to toggle source
 
               # File dl/mkcall.rb, line 11
def output_args(types)
  t = []
  types[1..-1].each_with_index{|x,i| t.push(output_arg(x,i))}
  t.join(",")
end
            
output_callfunc(types) click to toggle source
 
               # File dl/mkcall.rb, line 17
def output_callfunc(types)
  t = types[0]
  stmem = DLTYPE[t][:stmem]
  ctypes = types2ctypes(types)
  if( t == VOID )
    callstm = "(*f)(#{output_args(types)})"
  else
    callstm = "ret.#{stmem} = (*f)(#{output_args(types)})"
  end
  [ "{",
    "#{ctypes[0]} (*f)(#{ctypes[1..-1].join(',')}) = func;",
    "#{callstm};",
    "}"].join(" ")
end
            
output_case(types) click to toggle source
 
               # File dl/mkcall.rb, line 32
def output_case(types)
  num = types2num(types)
  callfunc_stm = output_callfunc(types)
<<EOF
  case #{num}:
#ifdef DEBUG
    printf("#{callfunc_stm}\\n");
#endif
    #{callfunc_stm};
    break;
EOF
end
            
rec_output(types = [VOID]) click to toggle source
 
               # File dl/mkcall.rb, line 45
def rec_output(types = [VOID])
  print output_case(types)
  if( types.length <= MAX_ARG )
    DLTYPE.keys.sort.each{|t|
      if( t != VOID && DLTYPE[t][:sym] )
        rec_output(types + [t])
      end
    }
  end
end
            
tget(t, i) click to toggle source
 
               # File dl/type.rb, line 84
def tget(t, i)
  (t & (0x07 << (i * 3))) >> (i * 3)
end
            
tpush(t, x) click to toggle source
 
               # File dl/type.rb, line 80
def tpush(t, x)
  (t << 3)|x
end
            
types2ctypes(types) click to toggle source
 
               # File dl/type.rb, line 109
def types2ctypes(types)
  res = []
  types.each{|t|
    res.push(DLTYPE[t][:ctype])
  }
  res
end
            
types2num(types) click to toggle source
 
               # File dl/type.rb, line 88
def types2num(types)
  res = 0x00
  r = types.reverse
  r.each{|t|
    res = tpush(res,t)
  }
  res
end
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus