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