ext/dl/mkcallback.rb


DEFINITIONS

This source file includes following functions.


   1  # -*- ruby -*-
   2  
   3  require 'mkmf'
   4  $:.unshift File.dirname(__FILE__)
   5  require 'type'
   6  require 'dlconfig'
   7  
   8  def mkfunc(rettype, fnum, argc)
   9    args = (0..(argc-1)).collect{|i| "long arg#{i}"}.join(", ")
  10  
  11    subst_code = (0..(argc-1)).collect{|i|
  12      "  buff[#{i.to_s}] = arg#{i.to_s};"
  13    }.join("\n")
  14  
  15    ret_code =
  16      if( DLTYPE[rettype][:c2rb] )
  17        "  return #{DLTYPE[rettype][:rb2c]['retval']};"
  18      else
  19        "  /* no return value */"
  20      end
  21  
  22    code = [
  23      "static #{DLTYPE[rettype][:ctype]}",
  24      "rb_dl_callback_func_#{rettype.to_s}_#{fnum.to_s}(#{args})",
  25      "{",
  26      "  VALUE retval, proto, proc, obj;",
  27      "  VALUE argv[#{argc.to_s}];",
  28      "  int  argc;",
  29      "  long buff[#{argc.to_s}];",
  30      "",
  31      subst_code,
  32      "",
  33      "  obj = rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(#{rettype.to_s}),INT2NUM(#{fnum.to_s})));",
  34      "  proto = rb_ary_entry(obj, 0);",
  35      "  proc  = rb_ary_entry(obj, 1);",
  36      "  Check_Type(proto, T_STRING);",
  37      "  if( RSTRING(proto)->len >= #{argc.to_s} )",
  38      "    rb_raise(rb_eArgError, \"too many arguments\");",
  39      "  rb_dl_scan_callback_args(buff, RSTRING(proto)->ptr, &argc, argv);",
  40      "  retval = rb_funcall2(proc, id_call, argc, argv);",
  41      "",
  42      ret_code,
  43      "}",
  44    ].join("\n")
  45  
  46    return code
  47  end
  48  
  49  DLTYPE.keys.sort.each{|t|
  50    for n in 0..(MAX_CALLBACK - 1)
  51      print(mkfunc(t, n, 15), "\n\n")
  52    end
  53  }