diff --git a/ext/dl/depend b/ext/dl/depend deleted file mode 100644 index fba3df7a3d..0000000000 --- a/ext/dl/depend +++ /dev/null @@ -1,46 +0,0 @@ -LDSHARED_TEST = $(LDSHARED) $(LDFLAGS) test/test.o -o test/libtest.so $(LOCAL_LIBS) - -libtest.so: test/libtest.so - -test/libtest.so: test/test.o $(srcdir)/test/libtest.def - $(RUBY) -rftools -e 'ARGV.each do|d|File.mkpath(File.dirname(d))end' $@ - $(LDSHARED_TEST:dl.def=test/libtest.def) - -test/test.o: $(srcdir)/test/test.c - @$(RUBY) -rftools -e 'File.mkpath(*ARGV)' test - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/test/test.c -o $@ - -test:: dl.so libtest.so force - $(RUBY) -I. -I$(srcdir)/lib $(srcdir)/test/test.rb - -force: - -.PHONY: force test - -allclean: distclean - @rm -f $(CLEANFILES) $(DISTCLEANFILES) - -$(OBJS): ./dlconfig.h - -sym.o: dl.h call.func - -dl.o: dl.h callback.func cbtable.func - -ptr.o: dl.h - -handle.o: dl.h - -call.func: $(srcdir)/mkcall.rb ./dlconfig.rb - @echo "Generating call.func" - @$(RUBY) $(srcdir)/mkcall.rb > $@ - -callback.func: $(srcdir)/mkcallback.rb ./dlconfig.rb - @echo "Generating callback.func" - @$(RUBY) $(srcdir)/mkcallback.rb > $@ - -cbtable.func: $(srcdir)/mkcbtable.rb ./dlconfig.rb - @echo "Generating cbtable.func" - @$(RUBY) $(srcdir)/mkcbtable.rb > $@ - -debug: - $(MAKE) CPPFLAGS="$(CPPFLAGS) -DDEBUG" diff --git a/ext/dl/dl.c b/ext/dl/dl.c deleted file mode 100644 index d92347158f..0000000000 --- a/ext/dl/dl.c +++ /dev/null @@ -1,721 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- -/* - * $Id$ - */ - -#include -#include -#include -#include "dl.h" - -VALUE rb_mDL; -VALUE rb_eDLError; -VALUE rb_eDLTypeError; - -static VALUE DLFuncTable; -static void *rb_dl_callback_table[CALLBACK_TYPES][MAX_CALLBACK]; -static ID id_call; - -static int -rb_dl_scan_callback_args(long stack[], const char *proto, - int *argc, VALUE argv[]) -{ - int i; - long *sp; - VALUE val; - - sp = stack; - for (i=1; proto[i]; i++) { - switch (proto[i]) { - case 'C': - { - char v; - v = (char)(*sp); - sp++; - val = INT2NUM(v); - } - break; - case 'H': - { - short v; - v = (short)(*sp); - sp++; - val = INT2NUM(v); - } - break; - case 'I': - { - int v; - v = (int)(*sp); - sp++; - val = INT2NUM(v); - } - break; - case 'L': - { - long v; - v = (long)(*sp); - sp++; - val = INT2NUM(v); - } - break; - case 'F': - { - float v; - memcpy(&v, sp, sizeof(float)); - sp += sizeof(float)/sizeof(long); - val = rb_float_new(v); - } - break; - case 'D': - { - double v; - memcpy(&v, sp, sizeof(double)); - sp += sizeof(double)/sizeof(long); - val = rb_float_new(v); - } - break; - case 'P': - { - void *v; - memcpy(&v, sp, sizeof(void*)); - sp++; - val = rb_dlptr_new(v, 0, 0); - } - break; - case 'S': - { - char *v; - memcpy(&v, sp, sizeof(void*)); - sp++; - val = rb_tainted_str_new2(v); - } - break; - default: - rb_raise(rb_eDLTypeError, "scan_callback_args: unsupported type `%c'", proto[i]); - break; - } - argv[i-1] = val; - } - *argc = (i - 1); - - return (*argc); -} - -#include "callback.func" - -static void -init_dl_func_table(){ -#include "cbtable.func" -} - -void * -dlmalloc(size_t size) -{ - DEBUG_CODE2({ - void *ptr; - - printf("dlmalloc(%d)",size); - ptr = xmalloc(size); - printf(":0x%x\n",ptr); - return ptr; - }, - { - return xmalloc(size); - }); -} - -void * -dlrealloc(void *ptr, size_t size) -{ - DEBUG_CODE({ - printf("dlrealloc(0x%x,%d)\n",ptr,size); - }); - return xrealloc(ptr, size); -} - -void -dlfree(void *ptr) -{ - DEBUG_CODE({ - printf("dlfree(0x%x)\n",ptr); - }); - xfree(ptr); -} - -char* -dlstrdup(const char *str) -{ - char *newstr; - - newstr = (char*)dlmalloc(strlen(str)); - strcpy(newstr,str); - - return newstr; -} - -size_t -dlsizeof(const char *cstr) -{ - size_t size; - int i, len, n, dlen; - char *d; - - len = strlen(cstr); - size = 0; - for (i=0; ilen; - *size = sizeof(float) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - case T_FLOAT: - ary[i] = (float)(RFLOAT(e)->value); - break; - case T_NIL: - ary[i] = 0.0; - break; - default: - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - break; - } - } - - return ary; -} - -static double * -c_darray(VALUE v, long *size) -{ - int i, len; - double *ary; - VALUE e; - - len = RARRAY(v)->len; - *size = sizeof(double) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - case T_FLOAT: - ary[i] = (double)(RFLOAT(e)->value); - break; - case T_NIL: - ary[i] = 0.0; - break; - default: - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - break; - } - } - - return ary; -} - -static long * -c_larray(VALUE v, long *size) -{ - int i, len; - long *ary; - VALUE e; - - len = RARRAY(v)->len; - *size = sizeof(long) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - case T_FIXNUM: - case T_BIGNUM: - ary[i] = (long)(NUM2INT(e)); - break; - case T_NIL: - ary[i] = 0; - break; - default: - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - break; - } - } - - return ary; -} - -static int * -c_iarray(VALUE v, long *size) -{ - int i, len; - int *ary; - VALUE e; - - len = RARRAY(v)->len; - *size = sizeof(int) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - case T_FIXNUM: - case T_BIGNUM: - ary[i] = (int)(NUM2INT(e)); - break; - case T_NIL: - ary[i] = 0; - break; - default: - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - break; - } - } - - return ary; -} - -static short * -c_harray(VALUE v, long *size) -{ - int i, len; - short *ary; - VALUE e; - - len = RARRAY(v)->len; - *size = sizeof(short) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - case T_FIXNUM: - case T_BIGNUM: - ary[i] = (short)(NUM2INT(e)); - break; - case T_NIL: - ary[i] = 0; - break; - default: - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - break; - } - } - - return ary; -} - -static char * -c_carray(VALUE v, long *size) -{ - int i, len; - char *ary; - VALUE e; - - len = RARRAY(v)->len; - *size = sizeof(char) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - case T_FIXNUM: - case T_BIGNUM: - ary[i] = (char)(NUM2INT(e)); - break; - case T_NIL: - ary[i] = 0; - break; - default: - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - break; - } - } - - return ary; -} - -static void * -c_parray(VALUE v, long *size) -{ - int i, len; - void **ary; - VALUE e, tmp; - - len = RARRAY(v)->len; - *size = sizeof(void*) * len; - ary = dlmalloc(*size); - for (i=0; i < len; i++) { - e = rb_ary_entry(v, i); - switch (TYPE(e)) { - default: - tmp = rb_check_string_type(e); - if (NIL_P(tmp)) { - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - } - e = tmp; - /* fall through */ - case T_STRING: - rb_check_safe_str(e); - { - char *str, *src; - src = RSTRING(e)->ptr; - str = dlstrdup(src); - ary[i] = (void*)str; - } - break; - case T_NIL: - ary[i] = NULL; - break; - case T_DATA: - if (rb_obj_is_kind_of(e, rb_cDLPtrData)) { - struct ptr_data *pdata; - Data_Get_Struct(e, struct ptr_data, pdata); - ary[i] = (void*)(pdata->ptr); - } - else{ - rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i); - } - break; - } - } - - return ary; -} - -void * -rb_ary2cary(char t, VALUE v, long *size) -{ - int len; - VALUE val0; - - val0 = rb_check_array_type(v); - if(NIL_P(TYPE(val0))) { - rb_raise(rb_eDLTypeError, "an array is expected."); - } - v = val0; - - len = RARRAY(v)->len; - if (len == 0) { - return NULL; - } - - if (!size) { - size = ALLOCA_N(long,1); - } - - val0 = rb_ary_entry(v,0); - switch (TYPE(val0)) { - case T_FIXNUM: - case T_BIGNUM: - switch (t) { - case 'C': case 'c': - return (void*)c_carray(v,size); - case 'H': case 'h': - return (void*)c_harray(v,size); - case 'I': case 'i': - return (void*)c_iarray(v,size); - case 'L': case 'l': case 0: - return (void*)c_larray(v,size); - default: - rb_raise(rb_eDLTypeError, "type mismatch"); - } - case T_STRING: - return (void*)c_parray(v,size); - case T_FLOAT: - switch (t) { - case 'F': case 'f': - return (void*)c_farray(v,size); - case 'D': case 'd': case 0: - return (void*)c_darray(v,size); - } - rb_raise(rb_eDLTypeError, "type mismatch"); - case T_DATA: - if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) { - return (void*)c_parray(v,size); - } - rb_raise(rb_eDLTypeError, "type mismatch"); - case T_NIL: - return (void*)c_parray(v, size); - default: - rb_raise(rb_eDLTypeError, "unsupported type"); - } -} - -VALUE -rb_str_to_ptr(VALUE self) -{ - char *ptr; - int len; - - len = RSTRING(self)->len; - ptr = (char*)dlmalloc(len + 1); - memcpy(ptr, RSTRING(self)->ptr, len); - ptr[len] = '\0'; - return rb_dlptr_new((void*)ptr,len,dlfree); -} - -VALUE -rb_ary_to_ptr(int argc, VALUE argv[], VALUE self) -{ - void *ptr; - VALUE t; - long size; - - switch (rb_scan_args(argc, argv, "01", &t)) { - case 1: - ptr = rb_ary2cary(StringValuePtr(t)[0], self, &size); - break; - case 0: - ptr = rb_ary2cary(0, self, &size); - break; - } - return ptr ? rb_dlptr_new(ptr, size, dlfree) : Qnil; -} - -VALUE -rb_io_to_ptr(VALUE self) -{ - OpenFile *fptr; - FILE *fp; - - GetOpenFile(self, fptr); - fp = rb_io_stdio_file(fptr); - - return fp ? rb_dlptr_new(fp, sizeof(FILE), 0) : Qnil; -} - -VALUE -rb_dl_dlopen(int argc, VALUE argv[], VALUE self) -{ - rb_secure(4); - return rb_class_new_instance(argc, argv, rb_cDLHandle); -} - -VALUE -rb_dl_malloc(VALUE self, VALUE size) -{ - rb_secure(4); - return rb_dlptr_malloc(DLNUM2LONG(size), dlfree); -} - -VALUE -rb_dl_strdup(VALUE self, VALUE str) -{ - void *ptr; - long len; - - SafeStringValue(str); - len = RSTRING(str)->len; - ptr = memcpy(dlmalloc(len + 1), RSTRING(str)->ptr, len + 1); - ((char *)ptr)[len] = '\0'; - return rb_dlptr_new(ptr, len, dlfree); -} - -static VALUE -rb_dl_sizeof(VALUE self, VALUE str) -{ - return INT2NUM(dlsizeof(StringValuePtr(str))); -} - -static VALUE -rb_dl_callback(int argc, VALUE argv[], VALUE self) -{ - VALUE type, proc; - int rettype, entry, i; - char fname[127]; - - rb_secure(4); - proc = Qnil; - switch (rb_scan_args(argc, argv, "11", &type, &proc)) { - case 1: - if (rb_block_given_p()) { - proc = rb_block_proc(); - } - else{ - proc = Qnil; - } - default: - break; - } - - StringValue(type); - switch (RSTRING(type)->ptr[0]) { - case '0': - rettype = 0x00; - break; - case 'C': - rettype = 0x01; - break; - case 'H': - rettype = 0x02; - break; - case 'I': - rettype = 0x03; - break; - case 'L': - rettype = 0x04; - break; - case 'F': - rettype = 0x05; - break; - case 'D': - rettype = 0x06; - break; - case 'P': - rettype = 0x07; - break; - default: - rb_raise(rb_eDLTypeError, "unsupported type `%c'", RSTRING(type)->ptr[0]); - } - - entry = -1; - for (i=0; i < MAX_CALLBACK; i++) { - if (rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil) { - entry = i; - break; - } - } - if (entry < 0) { - rb_raise(rb_eDLError, "too many callbacks are defined."); - } - - rb_hash_aset(DLFuncTable, - rb_assoc_new(INT2NUM(rettype),INT2NUM(entry)), - rb_assoc_new(type,proc)); - sprintf(fname, "rb_dl_callback_func_%d_%d", rettype, entry); - return rb_dlsym_new((void (*)())rb_dl_callback_table[rettype][entry], - fname, RSTRING(type)->ptr); -} - -static VALUE -rb_dl_remove_callback(VALUE mod, VALUE sym) -{ - freefunc_t f; - int i, j; - - rb_secure(4); - f = rb_dlsym2csym(sym); - for (i=0; i < CALLBACK_TYPES; i++) { - for (j=0; j < MAX_CALLBACK; j++) { - if (rb_dl_callback_table[i][j] == f) { - rb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil); - break; - } - } - } - return Qnil; -} - -void -Init_dl() -{ - void Init_dlptr(); - void Init_dlsym(); - void Init_dlhandle(); - - id_call = rb_intern("call"); - - rb_mDL = rb_define_module("DL"); - - rb_eDLError = rb_define_class_under(rb_mDL, "DLError", rb_eStandardError); - rb_eDLTypeError = rb_define_class_under(rb_mDL, "DLTypeError", rb_eDLError); - - DLFuncTable = rb_hash_new(); - init_dl_func_table(); - rb_define_const(rb_mDL, "FuncTable", DLFuncTable); - - rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL)); - rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY)); - rb_define_const(rb_mDL, "RTLD_NOW", INT2NUM(RTLD_NOW)); - - rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT)); - rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG)); - rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT)); - rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT)); - rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE)); - rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP)); - - rb_define_const(rb_mDL, "MAX_ARG", INT2NUM(MAX_ARG)); - rb_define_const(rb_mDL, "DLSTACK", rb_tainted_str_new2(DLSTACK_METHOD)); - - rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1); - rb_define_module_function(rb_mDL, "callback", rb_dl_callback, -1); - rb_define_module_function(rb_mDL, "define_callback", rb_dl_callback, -1); - rb_define_module_function(rb_mDL, "remove_callback", rb_dl_remove_callback, 1); - rb_define_module_function(rb_mDL, "malloc", rb_dl_malloc, 1); - rb_define_module_function(rb_mDL, "strdup", rb_dl_strdup, 1); - rb_define_module_function(rb_mDL, "sizeof", rb_dl_sizeof, 1); - - Init_dlptr(); - Init_dlsym(); - Init_dlhandle(); - - rb_define_const(rb_mDL, "FREE", rb_dlsym_new(dlfree, "free", "0P")); - - rb_define_method(rb_cString, "to_ptr", rb_str_to_ptr, 0); - rb_define_method(rb_cArray, "to_ptr", rb_ary_to_ptr, -1); - rb_define_method(rb_cIO, "to_ptr", rb_io_to_ptr, 0); -} diff --git a/ext/dl/dl.def b/ext/dl/dl.def deleted file mode 100644 index cdab4af90d..0000000000 --- a/ext/dl/dl.def +++ /dev/null @@ -1,59 +0,0 @@ -EXPORTS -Init_dl -dlfree -dlmalloc -dlrealloc -dlstrdup -rb_ary_to_ptr -rb_dl_dlopen -rb_dl_malloc -rb_dl_strdup -rb_eDLError -rb_eDLTypeError -rb_io_to_ptr -rb_mDL -rb_str_to_ptr -Init_dlhandle -rb_cDLHandle -rb_dlhandle_close -rb_dlhandle_disable_close -rb_dlhandle_enable_close -rb_dlhandle_sym -Init_dlptr -rb_cDLPtrData -rb_dlmem_each -rb_dlptr2cptr -rb_dlptr_malloc -rb_dlptr_aref -rb_dlptr_aset -rb_dlptr_cmp -rb_dlptr_define_data_type -rb_dlptr_define_struct -rb_dlptr_define_union -rb_dlptr_eql -rb_dlptr_free_get -rb_dlptr_free_set -rb_dlptr_get_data_type -rb_dlptr_inspect -rb_dlptr_minus -rb_dlptr_new -rb_dlptr_new2 -rb_dlptr_null_p -rb_dlptr_plus -rb_dlptr_ptr -rb_dlptr_ref -rb_dlptr_to_array -rb_dlptr_to_i -rb_dlptr_to_s -rb_dlptr_to_str -rb_mDLMemorySpace -Init_dlsym -rb_cDLSymbol -rb_dlsym2csym -rb_dlsym_call -rb_dlsym_cproto -rb_dlsym_inspect -rb_dlsym_name -rb_dlsym_new -rb_dlsym_proto -rb_dlsym_to_ptr diff --git a/ext/dl/dl.h b/ext/dl/dl.h deleted file mode 100644 index 83aa5df108..0000000000 --- a/ext/dl/dl.h +++ /dev/null @@ -1,313 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- - * $Id$ - */ - -#ifndef RUBY_DL_H -#define RUBY_DL_H - -#include -#include - -#if defined(HAVE_DLFCN_H) -# include -# /* some stranger systems may not define all of these */ -#ifndef RTLD_LAZY -#define RTLD_LAZY 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#else -# if defined(HAVE_WINDOWS_H) -# include -# define dlclose(ptr) FreeLibrary((HINSTANCE)ptr) -# define dlopen(name,flag) ((void*)LoadLibrary(name)) -# define dlerror() "unknown error" -# define dlsym(handle,name) ((void*)GetProcAddress(handle,name)) -# define RTLD_LAZY -1 -# define RTLD_NOW -1 -# define RTLD_GLOBAL -1 -# endif -#endif - -#if !defined(StringValue) -# define StringValue(v) if(TYPE(v) != T_STRING) v = rb_str_to_str(v) -#endif -#if !defined(StringValuePtr) -# define StringValuePtr(v) RSTRING((TYPE(v) == T_STRING) ? (v) : rb_str_to_str(v))->ptr -#endif - -#ifdef DEBUG -#define DEBUG_CODE(b) {printf("DEBUG:%d\n",__LINE__);b;} -#define DEBUG_CODE2(b1,b2) {printf("DEBUG:%d\n",__LINE__);b1;} -#else -#define DEBUG_CODE(b) -#define DEBUG_CODE2(b1,b2) b2 -#endif - -#define VOID_DLTYPE 0x00 -#define CHAR_DLTYPE 0x01 -#define SHORT_DLTYPE 0x02 -#define INT_DLTYPE 0x03 -#define LONG_DLTYPE 0x04 -#define FLOAT_DLTYPE 0x05 -#define DOUBLE_DLTYPE 0x06 -#define VOIDP_DLTYPE 0x07 - -#define ARG_TYPE(x,i) (((x) & (0x07 << ((i)*3))) >> ((i)*3)) -#define PUSH_ARG(x,t) do{x <<= 3; x |= t;}while(0) -#define PUSH_0(x) PUSH_ARG(x,VOID_DLTYPE) - -#if SIZEOF_INT == SIZEOF_LONG -# define PUSH_I(x) PUSH_ARG(x,LONG_DLTYPE) -# define ANY2I(x) x.l -# define DLINT(x) (long)x -#else -# define PUSH_I(x) PUSH_ARG(x,INT_DLTYPE) -# define ANY2I(x) x.i -# define DLINT(x) (int)x -#endif -#define PUSH_L(x) PUSH_ARG(x,LONG_DLTYPE) -#define ANY2L(x) x.l -#define DLLONG(x) (long)x - -#if defined(WITH_TYPE_FLOAT) -# if SIZEOF_FLOAT == SIZEOF_DOUBLE -# define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE) -# define ANY2F(x) (x.d) -# define DLFLOAT(x) ((double)x) -# else -# define PUSH_F(x) PUSH_ARG(x,FLOAT_DLTYPE) -# define ANY2F(x) (x.f) -# define DLFLOAT(x) ((float)x) -# endif -#else -# define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE) -# define ANY2F(x) (x.d) -# define DLFLOAT(x) ((double)x) -#endif -#define PUSH_D(x) PUSH_ARG(x,DOUBLE_DLTYPE) -#define ANY2D(x) (x.d) -#define DLDOUBLE(x) ((double)x) - -#if SIZEOF_INT == SIZEOF_VOIDP && SIZEOF_INT != SIZEOF_LONG -# define PUSH_P(x) PUSH_ARG(x,INT_DLTYPE) -# define ANY2P(x) (x.i) -# define DLVOIDP(x) ((int)x) -#elif SIZEOF_LONG == SIZEOF_VOIDP -# define PUSH_P(x) PUSH_ARG(x,LONG_DLTYPE) -# define ANY2P(x) (x.l) -# define DLVOIDP(x) ((long)x) -#else -# define PUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE) -# define ANY2P(x) (x.p) -# define DLVOIDP(x) ((void*)p) -#endif - -#if defined(WITH_TYPE_CHAR) -# define PUSH_C(x) PUSH_ARG(x,CHAR_DLTYPE) -# define ANY2C(x) (x.c) -# define DLCHAR(x) ((char)x) -#else -# define PUSH_C(x) PUSH_I(x) -# define ANY2C(x) ANY2I(x) -# define DLCHAR(x) DLINT(x) -#endif - -#if defined(WITH_TYPE_SHORT) -# define PUSH_H(x) PUSH_ARG(x,SHORT_DLTYPE) -# define ANY2H(x) (x.h) -# define DLSHORT(x) ((short)x) -#else -# define PUSH_H(x) PUSH_I(x) -# define ANY2H(x) ANY2I(x) -# define DLSHORT(x) DLINT(x) -#endif - -#define PUSH_S(x) PUSH_P(x) -#define ANY2S(x) ANY2P(x) -#define DLSTR(x) DLVOIDP(x) - -#define CBPUSH_0(x) PUSH_0(x) -#define CBPUSH_C(x) PUSH_C(x) -#define CBPUSH_H(x) PUSH_H(x) -#define CBPUSH_I(x) PUSH_I(x) -#define CBPUSH_L(x) PUSH_L(x) -#define CBPUSH_F(x) PUSH_F(x) -#define CBPUSH_D(x) PUSH_D(x) -#if defined(WITH_CBTYPE_VOIDP) -# define CBPUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE) -#else -# define CBPUSH_P(x) PUSH_P(x) -#endif - - -#if defined(USE_INLINE_ASM) -# if defined(__i386__) && defined(__GNUC__) -# define DLSTACK -# define DLSTACK_METHOD "asm" -# define DLSTACK_REVERSE -# define DLSTACK_PROTO -# define DLSTACK_ARGS -# define DLSTACK_START(sym) -# define DLSTACK_END(sym) -# define DLSTACK_PUSH_C(x) asm volatile ("pushl %0" :: "g" (x)); -# define DLSTACK_PUSH_H(x) asm volatile ("pushl %0" :: "g" (x)); -# define DLSTACK_PUSH_I(x) asm volatile ("pushl %0" :: "g" (x)); -# define DLSTACK_PUSH_L(x) asm volatile ("pushl %0" :: "g" (x)); -# define DLSTACK_PUSH_P(x) asm volatile ("pushl %0" :: "g" (x)); -# define DLSTACK_PUSH_F(x) asm volatile ("flds %0"::"g"(x));\ - asm volatile ("subl $4,%esp");\ - asm volatile ("fstps (%esp)"); -# define DLSTACK_PUSH_D(x) asm volatile ("fldl %0"::"g"(x));\ - asm volatile ("subl $8,%esp");\ - asm volatile ("fstpl (%esp)") -# else -# error --with-asm is not supported on this machine -# endif -#elif defined(USE_DLSTACK) -# define DLSTACK -# define DLSTACK_GUARD -# define DLSTACK_METHOD "dl" -# define DLSTACK_PROTO long,long,long,long,long,\ - long,long,long,long,long,\ - long,long,long,long,long -# define DLSTACK_ARGS stack[0],stack[1],stack[2],stack[3],stack[4],\ - stack[5],stack[6],stack[7],stack[8],stack[9],\ - stack[10],stack[11],stack[12],stack[13],stack[14] -# define DLSTACK_SIZE (sizeof(long)*15) -# define DLSTACK_START(sym) -# define DLSTACK_END(sym) -# define DLSTACK_PUSH_C(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} -# define DLSTACK_PUSH_H(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} -# define DLSTACK_PUSH_I(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} -# define DLSTACK_PUSH_L(x) memcpy(sp,&x,sizeof(long)); sp++; -# define DLSTACK_PUSH_P(x) memcpy(sp,&x,sizeof(void*)); sp++; -# define DLSTACK_PUSH_F(x) memcpy(sp,&x,sizeof(float)); sp+=sizeof(float)/sizeof(long); -# define DLSTACK_PUSH_D(x) memcpy(sp,&x,sizeof(double)); sp+=sizeof(double)/sizeof(long); -#else -# define DLSTACK_METHOD "none" -#endif - -extern VALUE rb_mDL; -extern VALUE rb_mDLMemorySpace; -extern VALUE rb_cDLHandle; -extern VALUE rb_cDLSymbol; -extern VALUE rb_cDLPtrData; -extern VALUE rb_cDLStructData; - -extern VALUE rb_eDLError; -extern VALUE rb_eDLTypeError; - -#if defined(LONG2NUM) && (SIZEOF_LONG == SIZEOF_VOIDP) -# define DLLONG2NUM(x) LONG2NUM((long)x) -# define DLNUM2LONG(x) (long)(NUM2LONG(x)) -#else -# define DLLONG2NUM(x) INT2NUM((long)x) -# define DLNUM2LONG(x) (long)(NUM2INT(x)) -#endif - -typedef struct { char c; void *x; } s_voidp; -typedef struct { char c; short x; } s_short; -typedef struct { char c; int x; } s_int; -typedef struct { char c; long x; } s_long; -typedef struct { char c; float x; } s_float; -typedef struct { char c; double x; } s_double; - -#define ALIGN_VOIDP (sizeof(s_voidp) - sizeof(void *)) -#define ALIGN_SHORT (sizeof(s_short) - sizeof(short)) -#define ALIGN_INT (sizeof(s_int) - sizeof(int)) -#define ALIGN_LONG (sizeof(s_long) - sizeof(long)) -#define ALIGN_FLOAT (sizeof(s_float) - sizeof(float)) -#define ALIGN_DOUBLE (sizeof(s_double) - sizeof(double)) - -/* for compatibility */ -#define VOIDP_ALIGN ALIGN_VOIDP -#define SHORT_ALIGN ALIGN_SHORT -#define INT_ALIGN ALIGN_INT -#define LONG_ALIGN ALIGN_LONG -#define FLOAT_ALIGN ALIGN_FLOAT -#define DOUBLE_ALIGN ALIGN_DOUBLE - -#define DLALIGN(ptr,offset,align) {\ - while( (((unsigned long)((char *)ptr + offset)) % align) != 0 ) offset++;\ -} - -typedef void (*freefunc_t)(void *); -#define DLFREEFUNC(func) ((freefunc_t)(func)) - -typedef union { - void* p; - char c; - short h; - int i; - long l; - float f; - double d; - char *s; -} ANY_TYPE; - -struct dl_handle { - void *ptr; - int open; - int enable_close; -}; - -struct sym_data { - void *func; - char *name; - char *type; - int len; -}; - -enum DLPTR_CTYPE { - DLPTR_CTYPE_UNKNOWN, - DLPTR_CTYPE_STRUCT, - DLPTR_CTYPE_UNION -}; - -struct ptr_data { - void *ptr; /* a pointer to the data */ - freefunc_t free; /* free() */ - char *stype; /* array of type specifiers */ - int *ssize; /* size[i] = sizeof(type[i]) > 0 */ - int slen; /* the number of type specifiers */ - ID *ids; - int ids_num; - int ctype; /* DLPTR_CTYPE_UNKNOWN, DLPTR_CTYPE_STRUCT, DLPTR_CTYPE_UNION */ - long size; -}; - -#define RDLPTR(obj) ((struct ptr_data *)(DATA_PTR(obj))) -#define RDLSYM(obj) ((struct sym_data *)(DATA_PTR(obj))) - -void dlfree(void*); -void *dlmalloc(size_t); -void *dlrealloc(void*,size_t); -char *dlstrdup(const char *); -size_t dlsizeof(const char *); - -void *rb_ary2cary(char t, VALUE ary, long *size); - -/* -void rb_dlmem_delete(void *ptr); -void rb_dlmem_aset(void *ptr, VALUE obj); -VALUE rb_dlmem_aref(void *ptr); -*/ - -void dlptr_free(struct ptr_data *data); -void dlptr_init(VALUE val); - -VALUE rb_dlptr_new(void *ptr, long size, freefunc_t func); -VALUE rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func); -VALUE rb_dlptr_malloc(long size, freefunc_t func); -void *rb_dlptr2cptr(VALUE val); - -VALUE rb_dlsym_new(void (*func)(), const char *name, const char *type); -freefunc_t rb_dlsym2csym(VALUE val); - - -#endif /* RUBY_DL_H */ diff --git a/ext/dl/doc/dl.txt b/ext/dl/doc/dl.txt deleted file mode 100644 index 893bd21d79..0000000000 --- a/ext/dl/doc/dl.txt +++ /dev/null @@ -1,266 +0,0 @@ -=begin - -= Ruby/DL - -Ruby/DL provides an interface to the dynamic linker such as dlopen() on UNIX -and LoadLibrary() on Windows. - -= Building and Installing - - $ ruby extconf.rb # to create the Makefile - $ make # to build the library 'dl.so' - $ make libtest.so # to build the C library 'libtest.so' for the test script - $ make test # to run the test script - $ make install # to install the library - $ make clean # to remove the created files without Makefile - $ make distclean # to remove the all created files - -= Using Ruby/DL - -We should usually use DL::Importable module provided by "dl/import.rb". -It has high-level functions to access library functions. We use -DL::Importable module to extend a module as follows: - - require "dl/import" - module LIBC - extend DL::Importable - end - -Now we can use methods dlload and extern in this module. We load the -libraries using dlload, and define wrapper methods to library functions -using extern respectively as follows: - - module LIBC - extend DL::Importable - dlload "libc.so.6","libm.so.6" - extern "int strlen(char*)" - end - # Note that we should not include the module LIBC from some reason. - -We can call the library function strlen() using LIBC.strlen. If the first -character of given function name is an uppercase, the first character of the -defined method name becomes lowercase. -We can also construct memory images of structures and unions using functions -struct and union which are defined in "dl/struct.rb" as follows: - - require "dl/import" - require "dl/struct" - module LIBC - extend DL::Importable - Timeval = struct [ # define timeval structure. - "long tv_sec", - "long tv_uses", - ] - end - val = LIBC::Timeval.malloc # allocate memory. - -Notice that the above example takes LIBC::Timeval.malloc to allocate memory, -rather than LIBC::Timeval.new. It is because DL::Timeval.new is for wrapping -an object, PtrData, which has already been created. - -We can define a callback using the module function "callback" as follows: - - module Foo - extend DL::Importable - def my_comp(str1,str2) - str1 <=> str2 - end - COMPARE = callback "int my_comp(char*,char*)" - end - -where Foo::COMPARE is a Symbol object which invokes the method "my_comp". - -DL::Importable module is very useful. However, we sometimes encounter a case -that we must directly use low-level functions such as dlsym(). In such case, -we would use DL module functions. They are described in next section. - -= DL module - -Module DL consists of three classes, a few module functions and constants. -The class Symbol represents the symbol we can call. The class PtrData -indicates a memory block such as a pointer in C. An object instantiated from -the class Handle keeps a handle to opened library. - -== Constants - -* VERSION -* MAJOR_VERSION -* MINOR_VERSION -* PATCH_VERSION -* RTLD_GLOBAL -* RTLD_LAZY -* RTLD_NOW -* MAX_ARG -* MAX_CBARG -* MAX_CBENT - -== Functions - -* handle = dlopen(lib){|handle| ... } - * is quite equal to `Handle.new(lib)' - -* sym = set_callback(cbtype, entry){|args| ... } -* sym = set_callback(cbtype, entry, proc) - * makes entry-th pre-defined function to call the proc or given block. the - entry-th pre-defined function is specified by cbtype and entry. cbtype is a - prototype of the callback. see also the section `Type specifiers' about - cbtype. - -* sym = get_callback(cbtype, entry) - * returns the Proc object which is given by the above function - `set_callback'. - -* ptr = malloc(size, [free = nil]) - * allocates the size bytes, and returns the pointer as a PtrData object ptr. - -* ptr = strdup(str) - * returns a PtrData object ptr which represents the pointer to a new string - which is a duplicate of the string str. - -* size = sizeof(type) - * returns the size of type. `sizeof("C") + sizeof("L")' is not equal to - `sizeof("CL")'. the latter is assumed to returns the enough size of the - structure `struct foo { char c; long l; }', but the size may not equal to - `sizeof(foo)' of C. - -== Handle class - -* handle = Handle.new(lib){|handle| ... } - * opens a library lib and returns a Handle object handle. if a block is - given, the handle is automatically closed as the block ends. - -* Handle#close - * closes the handle opened by the above Handle.new(lib). - -* sym = Handle#sym(func, prototype = "0"), - sym = Handle#[func, prototype = nil] - - * obtains the pointer to a function called func and returns a Symbol object - or a DataPtr object. prototype is a string which consists of type - specifiers, it indicates the function's prototype. see also the section - `Type specifiers'. - -== Symbol class - -* sym = Symbol.new(addr, type = nil, name = nil) - * creates the Symbol object sym with the type type if type is not nil. addr - is the address where the function is allocated. If type is nil, it returns - a DataPtr object. - -* Symbol::char2type(char) - * takes a character char that represents a type and returns the type - specifier of the C language. - -* str = Symbol#proto() - * returns the function prototype. - -* str = Symbol#name() - * Returns the function name. - -* str = Symbol#cproto(), - str = Symbol#to_s() - * returns the prototype of the C language. - -* str = Symbol#inspect() - * returns the inspectable string. - -* r,rs = Symbol#call(arg1,arg2,...,argN), - r,rs = Symbol#[](arg1,arg2,...,argN) - * calls the function with parameters arg1, arg2, ..., argN. and the result - consists of the return value r and parameters rs. rs is an array. - -* ptr = Symbol#to_ptr - * returns the corresponding PtrData object ptr. - -== PtrData class - -* ptr = PtrData.new(addr, [size = 0, free = nil]) - * returns the PtrData object representing the pointer which indicates the - address addr. GC frees the memory using the free function. - -* PtrData#free=(sym) - * If you specify a symbol object sym, GC frees the memory using the function - represented by sym. - -* sym = PtrData#free - * returns a symbol object sym which is used when GC frees the memory. it - usually configured by `PtrData#free=' or `PtrData.new'. - -* size = PtrData#size, PtrData#size=(size) - * gets and sets allocated size of the memory. - -* ary = PtrData#to_a(type, [size]) - * returns an array of the type which specified with type. type must be one of - 'S','P','I','L','D' and 'F'. - -* str = PtrData#to_s([len]) - * returns a string which length is len. if len is omitted, the end of the - string is '\0'. - -* ptr = PtrData#ptr,+@ - * returns the pointed value as a PtrData object ptr. - -* ptr = PtrData#ref,-@ - * returns the reference as a PtrData object ptr. - -* ptr = PtrData#+ - * returns the PtrData object - -* ptr = PtrData#- - * returns the PtrData object - -* PtrData#struct!(type, *members) - * defines the data type to get access to a structure member with a symbol. - (see also PtrData#[]) - -* PtrData#union!(type, *members) - * defines the data type to get access to a union member with a symbol. (see - also PtrData#[]) - -* val = PtrData#[key], PtrData#[key, num = 0] - * if the key is a string or symbol, this method returns the value of the - structure/union member which has the type defined by PtrData# - {struct!,union!}. if the key is a integer value and this object represents - the pointer ptr, it returns the value of `(ptr + key).to_s(num)' - -* PtrData#[key,num]=val, PtrData#[key]=val - * if the key is a string or symbol, this method substitute the value of the - structure/union member with val. if the key is a integer value and val is a - string, this method copies num bytes of val to the memory area ptr using - memcpy(3). - -== Type specifiers - -the prototype consists of the following type specifiers, first element of -prototype represents the type of return value, and remaining elements represent -the type of each argument. - - C : char - c : char * - H : short - h : short * - I : int - i : int * - L : long - l : long * - F : float - f : float * - D : double - d : double * - S : const char * - s : char * - A : const type[] - a : type[] (allocates new memory space) - P : void * (same as 'p') - p : void * (same as 'P') - 0 : void function (this must be a first character of the prototype) - -the cbtype consists of type specifiers 0, C, I, H, L, F, D, S and P. -for example: - - DL.callback('IPP'){|ptr1,ptr2| - str1 = ptr1.ptr.to_s - str2 = ptr2.ptr.to_s - str1 <=> str2 - } -=end diff --git a/ext/dl/extconf.rb b/ext/dl/extconf.rb deleted file mode 100644 index beb15ab04c..0000000000 --- a/ext/dl/extconf.rb +++ /dev/null @@ -1,193 +0,0 @@ -require 'mkmf' - -begin # for the exception SystemExit - -$:.unshift File.dirname(__FILE__) -require 'type' - -if( ARGV.include?("--help") ) - print < - --with-callback= - --enable-asm use the embedded assembler for passing arguments. - (this option is available for i386 machine now.) - --enable-dlstack use a stack emulation for constructing function call. -EOF - exit(0) -end - -($CPPFLAGS || $CFLAGS) << " -I." - -if (Config::CONFIG['CC'] =~ /gcc/) # from Win32API - $CFLAGS << " -fno-defer-pop -fno-omit-frame-pointer" -end - -$with_dlstack ||= true -$with_asm = ! $with_dlstack - -$with_type_int = try_cpp(<\n") - exit(1) - end -end -max_arg ||= 6 - -max_callback = with_config("callback","10").to_i -callback_types = DLTYPE.keys.length - - -$dlconfig_h = <] [-d] [] -EOF -end - -while( ARGV[0] ) - case( ARGV[0] ) - when "-r" - ARGV.shift - $recursive = true - when "-R" - ARGV.shift - $recursive = false - when "-l" - ARGV.shift - $insert_require = true - when "-L" - ARGV.shift - $insert_require = false - when "-c" - ARGV.shift - $conly = true - when "-C" - ARGV.shift - $conly = false - when "-f" - ARGV.shift - $force = true - when "-F" - ARGV.shift - $force = false - when "-I" - ARGV.shift - $inc_path << ARGV.shift - when "-d" - ARGV.shift - $DEBUG = true - when "-h","--help" - print_usage() - exit 0 - when /-.*/ - $stderr.print("unknown option '#{ARGV[0]}'.\n") - print_usage() - exit 0 - else - $infilename = ARGV.shift - end -end - -$inc_dir = File.join(CONFIG["prefix"], "lib", "ruby", - CONFIG["MAJOR"] + "." + CONFIG["MINOR"], - "dl") - -class H2RBError < StandardError; end - - -class H2RB - def initialize(inc_dir = nil, inc_path = nil, insert_require = nil) - @inc_path = inc_path || [] - @inc_dir = inc_dir || '.' - @indent = 0 - @parsed_files = [] - @insert_require = insert_require || false - end - - def find_path(file) - if( ! file ) - return nil - end - if( File.exist?(file) ) - if( file[0] == ?/ ) - return file - else - return file - end - end - @inc_path.each{|path| - full = File.join(path, file) - if( File.exist?(full) ) - return full - end - } - return nil - end - - def strip_comment(line) - if( @commented ) - if( e = line.index("*/") ) - line[0..(e+1)] = "" - @commented = false - else - line = "" - end - else - if( s = line.index("/*") ) - if( e = line.index("*/") ) - line[s..(e+1)] = "" - else - line[s..-1] = "" - @commented = true - end - elsif( s = line.index("//") ) - line[s..(-1)] = "" - end - end - - line.gsub!(/\s+$/,"") - return line - end - - def up_indent - @indent += 1 - end - - def down_indent - @indent -= 1 - if( @indent < 0 ) - raise - end - end - - def indent - " " * @indent - end - - def rescue_begin - line = "#{indent}begin" - up_indent - return line - end - - def rescue_nameerror - down_indent - line = [ - "#{indent}rescue NameError => e", - "#{indent} raise e if( $DEBUG )", - "#{indent}end"].join($/) - return line - end - - def parse_enum(line) - if( line =~ /enum\s+(\S+\s+)?\{(.+)\}/ ) - enum_name = $1 - enum_block = $2 - if( enum_name ) - line = "#{indent}# -- enum #{enum_name}\n" - else - line = "#{indent}# -- enum\n" - end - enums = enum_block.split(/,/).collect{|e| e.strip} - i = 0 - enums.each{|elem| - var,val = elem.split(/=/).collect{|e| e.strip} - if( val ) - i = val.to_i - end - line += "#{indent}#{var} = #{i.to_s}\n" - i += 1 - } - line += "#{indent}# -- end of enum" - return line - else - return nil - end - end - - def parse_define(line) - case line - when /^#\s*define\s+(\S+)\(\)/ - line = nil - when /^#\s*define\s+(\S+)\((.+)\)\s+(.+)$/ - if( @conly ) - line = nil - else - defname = $1 - defargs = $2 - defval = $3 - if( !valid_ruby_code?(defval) ) - defval = "nil # #{defval}" - end - if( defname[0,1] =~ /^[A-Z]$/ ) - line = "#{indent}#{defname} = proc{|#{defargs}| #{defval}}" - else - line = [ - "#{indent}def #{defname}(#{defargs})", - "#{indent} #{defval}", - "#{indent}end" - ].join("\n") - end - end - when /^#\s*define\s+(\S+)\((.+)\)$/ - if( @conly ) - line = nil - else - defname = $1 - defargs = $2 - defval = nil - if( !valid_ruby_code?(defval) ) - defval = "nil # #{defval}" - end - if( defname[0,1] =~ /^[A-Z]$/ ) - line = "#{indent}#{defname} = proc{|#{defargs}| #{defval}}" - else - line = [ - "#{indent}def #{defname}(#{defargs})", - "#{indent} #{defval}", - "#{indent}end" - ].join("\n") - end - end - when /^#\s*define\s+(\S+)\s+(.+)$/ - defname = $1 - defval = $2 - if( !valid_ruby_code?(defval) ) - defval = "nil # #{defval}" - end - line = [rescue_begin, "#{indent}#{defname} = #{defval}", rescue_nameerror].join($/) - when /^#\s*define\s+(\S+)$/ - defname = $1 - line = "#{indent}#{defname} = nil" - else - line = nil - end - return line - end - - def parse_undef(line) - case line - when /^#\s*undef\s+([A-Z]\S+)$/ - defname = $1 - line = "#{indent}remove_const(:#{defname})" - when /^#\s*undef\s+(\S+)$/ - defname = $1 - line = "#{indent}#{defname} = nil" - else - line = nil - end - return line - end - - def parse_ifdef(line) - case line - when /^#\s*ifdef\s+(\S+)$/ - defname = $1 - line = [ - rescue_begin, - "#{indent}if( defined?(#{defname}) && ! #{defname}.nil? )"].join($/) - else - line = nil - end - return line - end - - def parse_ifndef(line) - case line - when /^#\s*ifndef\s+(\S+)$/ - defname = $1 - line = [ - rescue_begin, - "#{indent}if( ! defined?(#{defname}) || #{defname}.nil? )"].join($/) - else - line = nil - end - return line - end - - def parse_if(line) - case line - when /^#\s*if\s+(.+)$/ - cond = $1 - cond.gsub!(/defined(.+)/){ "defined?(#{$1}) && ! #{$1}.nil?" } - if( valid_ruby_code?(cond) ) - line = "#{indent}if( #{cond} )" - else - line = "#{indent}if( false ) # #{cond}" - end - line = [rescue_begin, line].join($/) - else - line = nil - end - return line - end - - def parse_elif(line) - case line - when /^#\s*elif\s+(.+)$/ - cond = $1 - cond.gsub!("defined","defined?") - line = "#{indent}elsif( #{cond} )" - else - line = nil - end - return line - end - - def parse_else(line) - case line - when /^#\s*else\s*/ - line = "#{indent}else" - else - line = nil - end - return line - end - - def parse_endif(line) - case line - when /^#\s*endif\s*$/ - line = ["#{indent}end", rescue_nameerror].join($/) - else - line = nil - end - return line - end - - def parse_include(line) - if( ! @insert_require ) - return nil - end - - file = nil - case line - when /^#\s*include "(.+)"$/ - file = $1 - line = "#{indent}require '#{file}'" - when /^#\s*include \<(.+)\>$/ - file = $1 - line = "#{indent}require '#{file}'" - else - line = nil - end - if( @recursive && file && (!@parsed_files.include?(file)) ) - parse(file, @recursive, @force, @conly) - end - return line - end - - - def open_files(infilename) - if( ! infilename ) - return [$stdin, $stdout] - end - - old_infilename = infilename - infilename = find_path(infilename) - if( ! infilename ) - $stderr.print("'#{old_infilename}' was not found.\n") - return [nil,nil] - end - - if( infilename ) - if( infilename[0,1] == '/' ) - outfilename = File.join(@inc_dir, infilename[1..-1] + ".rb") - else - outfilename = infilename + ".rb" - end - File.mkpath(File.dirname(outfilename)) - else - outfilename = nil - end - - if( infilename ) - fin = File.open(infilename,"r") - else - fin = $stdin - end - if( outfilename ) - if( File.exist?(outfilename) && (!@force) ) - $stderr.print("'#{outfilename}' have already existed.\n") - return [fin, nil] - end - fout = File.open(outfilename,"w") - else - fout = $stdout - end - - $stderr.print("#{infilename} -> #{outfilename}\n") - if( fout ) - dir = File.dirname(outfilename) - if( dir[0,1] != "." && dir != "" ) - fout.print("if( ! $LOAD_PATH.include?('#{dir}') )\n", - " $LOAD_PATH.push('#{dir}')\n", - "end\n") - end - end - return [fin,fout] - end - - def parse(infilename = nil, recursive = false, force = false, conly = false) - @commented = false - @recursive = recursive - @force = force - @conly = conly - @parsed_files << infilename - - fin,fout = open_files(infilename) - if( !fin ) - return - end - - begin - line_number = 0 - pre_line = nil - fin.each_line{|line| - line_number += 1 - line.chop! - if( $DEBUG ) - $stderr.print("#{line_number}:(#{@indent}):", line, "\n") - end - - if( pre_line ) - line = pre_line + line - pre_line = nil - end - - if( line[-1,1] == "\\" ) - pre_line = line[0..-2] - next - end - - if( eidx = line.index("enum ") ) - pre_line = line[eidx .. -1] - if( i = line.index("{") && j = line.index("}") ) - line = line[0..j] - pre_line = nil - else - next - end - end - - line = strip_comment(line) - case line - when /^enum\s/ - line = parse_enum(line) - when /^#\s*define\s/ - line = parse_define(line) - when /^#\s*undef\s/ - line = parse_undef(line) - when /^#\s*ifdef\s/ - line = parse_ifdef(line) - up_indent - when /^#\s*ifndef\s/ - line = parse_ifndef(line) - up_indent - when /^#\s*if\s/ - line = parse_if(line) - up_indent - when /^#\s*elif\s/ - down_indent - line = parse_elif(line) - up_indent - when /^#\s*else/ - down_indent - line = parse_else(line) - up_indent - when /^#\s*endif/ - down_indent - line = parse_endif(line) - when /^#\s*include\s/ - line = parse_include(line) - else - line = nil - end - if( line && fout ) - fout.print(line, " # #{line_number}",$/) - end - } - ensure - fin.close if fin - fout.close if fout - end - end -end - -h2rb = H2RB.new($inc_dir, $inc_path, $insert_require) -h2rb.parse($infilename, $recursive, $force, $conly) diff --git a/ext/dl/handle.c b/ext/dl/handle.c deleted file mode 100644 index 82eb1a8698..0000000000 --- a/ext/dl/handle.c +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- - * $Id$ - */ - -#include -#include "dl.h" - -VALUE rb_cDLHandle; - -void -dlhandle_free(struct dl_handle *dlhandle) -{ - if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) { - dlclose(dlhandle->ptr); - } -} - -VALUE -rb_dlhandle_close(VALUE self) -{ - struct dl_handle *dlhandle; - - Data_Get_Struct(self, struct dl_handle, dlhandle); - dlhandle->open = 0; - return INT2NUM(dlclose(dlhandle->ptr)); -} - -VALUE -rb_dlhandle_s_allocate(VALUE klass) -{ - VALUE obj; - struct dl_handle *dlhandle; - - obj = Data_Make_Struct(rb_cDLHandle, struct dl_handle, 0, - dlhandle_free, dlhandle); - dlhandle->ptr = 0; - dlhandle->open = 0; - dlhandle->enable_close = 0; - - return obj; -} - -VALUE -rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self) -{ - void *ptr; - struct dl_handle *dlhandle; - VALUE lib, flag; - char *clib; - int cflag; - const char *err; - - switch (rb_scan_args(argc, argv, "11", &lib, &flag)) { - case 1: - clib = NIL_P(lib) ? NULL : StringValuePtr(lib); - cflag = RTLD_LAZY | RTLD_GLOBAL; - break; - case 2: - clib = NIL_P(lib) ? NULL : StringValuePtr(lib); - cflag = NUM2INT(flag); - break; - default: - rb_bug("rb_dlhandle_new"); - } - - ptr = dlopen(clib, cflag); -#if defined(HAVE_DLERROR) - if (!ptr && (err = dlerror())) { - rb_raise(rb_eRuntimeError, err); - } -#else - if (!ptr) { - err = dlerror(); - rb_raise(rb_eRuntimeError, err); - } -#endif - Data_Get_Struct(self, struct dl_handle, dlhandle); - if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) { - dlclose(dlhandle->ptr); - } - dlhandle->ptr = ptr; - dlhandle->open = 1; - dlhandle->enable_close = 0; - - if (rb_block_given_p()) { - rb_ensure(rb_yield, self, rb_dlhandle_close, self); - } - - return Qnil; -} - -VALUE -rb_dlhandle_enable_close(VALUE self) -{ - struct dl_handle *dlhandle; - - Data_Get_Struct(self, struct dl_handle, dlhandle); - dlhandle->enable_close = 1; - return Qnil; -} - -VALUE -rb_dlhandle_disable_close(VALUE self) -{ - struct dl_handle *dlhandle; - - Data_Get_Struct(self, struct dl_handle, dlhandle); - dlhandle->enable_close = 0; - return Qnil; -} - -VALUE -rb_dlhandle_to_i(VALUE self) -{ - struct dl_handle *dlhandle; - - Data_Get_Struct(self, struct dl_handle, dlhandle); - return DLLONG2NUM(dlhandle); -} - -VALUE -rb_dlhandle_to_ptr(VALUE self) -{ - struct dl_handle *dlhandle; - - Data_Get_Struct(self, struct dl_handle, dlhandle); - return rb_dlptr_new(dlhandle, sizeof(dlhandle), 0); -} - -VALUE -rb_dlhandle_sym(int argc, VALUE argv[], VALUE self) -{ - VALUE sym, type; - void (*func)(); - VALUE val; - struct dl_handle *dlhandle; - void *handle; - const char *name, *stype; - const char *err; - - rb_secure(2); - if (rb_scan_args(argc, argv, "11", &sym, &type) == 2) { - SafeStringValue(type); - stype = StringValuePtr(type); - } - else{ - stype = NULL; - } - - if (sym == Qnil) { -#if defined(RTLD_NEXT) - name = RTLD_NEXT; -#else - name = NULL; -#endif - } - else{ - SafeStringValue(sym); - name = StringValuePtr(sym); - } - - Data_Get_Struct(self, struct dl_handle, dlhandle); - if (!dlhandle->open) { - rb_raise(rb_eRuntimeError, "Closed handle."); - } - handle = dlhandle->ptr; - - func = dlsym(handle, name); -#if defined(HAVE_DLERROR) - if (!func && (err = dlerror())) -#else - if (!func) -#endif - { -#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__) - { - int len = strlen(name); - char *name_a = (char*)dlmalloc(len+2); - strcpy(name_a, name); - name_a[len] = 'A'; - name_a[len+1] = '\0'; - func = dlsym(handle, name_a); - dlfree(name_a); -#if defined(HAVE_DLERROR) - if (!func && (err = dlerror())) -#else - if (!func) -#endif - { - rb_raise(rb_eRuntimeError, "Unknown symbol \"%sA\".", name); - } - } -#else - rb_raise(rb_eRuntimeError, "Unknown symbol \"%s\".", name); -#endif - } - val = rb_dlsym_new(func, name, stype); - - return val; -} - -void -Init_dlhandle() -{ - rb_cDLHandle = rb_define_class_under(rb_mDL, "Handle", rb_cObject); - rb_define_alloc_func(rb_cDLHandle, rb_dlhandle_s_allocate); - rb_define_method(rb_cDLHandle, "initialize", rb_dlhandle_initialize, -1); - rb_define_method(rb_cDLHandle, "to_i", rb_dlhandle_to_i, 0); - rb_define_method(rb_cDLHandle, "to_ptr", rb_dlhandle_to_ptr, 0); - rb_define_method(rb_cDLHandle, "close", rb_dlhandle_close, 0); - rb_define_method(rb_cDLHandle, "sym", rb_dlhandle_sym, -1); - rb_define_method(rb_cDLHandle, "[]", rb_dlhandle_sym, -1); - rb_define_method(rb_cDLHandle, "disable_close", rb_dlhandle_disable_close, 0); - rb_define_method(rb_cDLHandle, "enable_close", rb_dlhandle_enable_close, 0); -} diff --git a/ext/dl/install.rb b/ext/dl/install.rb deleted file mode 100644 index 69b1834301..0000000000 --- a/ext/dl/install.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'mkmf' -require 'ftools' - -SO_LIBS = ["dl.so"] - -$ruby_version = CONFIG['MAJOR'] + "." + CONFIG['MINOR'] -$prefix = CONFIG['prefix'] -$libdir = File.join($prefix,'lib') -$rubylibdir = File.join($libdir, 'ruby', $ruby_version) -$arch = CONFIG['arch'] -$archdir = File.join($rubylibdir, $arch) - -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 - -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 - -install() diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb deleted file mode 100644 index 2a98ace8ab..0000000000 --- a/ext/dl/lib/dl/import.rb +++ /dev/null @@ -1,224 +0,0 @@ -# -*- ruby -*- - -require 'dl' -require 'dl/types' - -module DL - module Importable - LIB_MAP = {} - - module Internal - def init_types() - @types ||= ::DL::Types.new - end - - def init_sym() - @SYM ||= {} - end - - def [](name) - return @SYM[name.to_s][0] - end - - def dlload(*libnames) - if( !defined?(@LIBS) ) - @LIBS = [] - end - libnames.each{|libname| - if( !LIB_MAP[libname] ) - LIB_MAP[libname] = DL.dlopen(libname) - end - @LIBS.push(LIB_MAP[libname]) - } - end - alias dllink :dlload - - def parse_cproto(proto) - proto = proto.gsub(/\s+/, " ").strip - case proto - when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/ - ret = $1 - args = $2 - ret = ret.split(/\s+/) - args = args.split(/\s*,\s*/) - func = ret.pop - if( func =~ /^\*/ ) - func.gsub!(/^\*+/,"") - ret.push("*") - end - ret = ret.join(" ") - return [func, ret, args] - else - raise(RuntimeError,"can't parse the function prototype: #{proto}") - end - end - - # example: - # extern "int strlen(char*)" - # - def extern(proto) - func,ret,args = parse_cproto(proto) - return import(func, ret, args) - end - - # example: - # callback "int method_name(int, char*)" - # - def callback(proto) - func,ret,args = parse_cproto(proto) - - init_types() - init_sym() - - rty,renc,rdec = @types.encode_return_type(ret) - if( !rty ) - raise(TypeError, "unsupported type: #{ret}") - end - ty,enc,dec = encode_argument_types(args) - symty = rty + ty - - module_eval("module_function :#{func}") - sym = module_eval([ - "DL::callback(\"#{symty}\"){|*args|", - " sym,rdec,enc,dec = @SYM['#{func}']", - " args = enc.call(args) if enc", - " r,rs = #{func}(*args)", - " r = renc.call(r) if rdec", - " rs = dec.call(rs) if (dec && rs)", - " @retval = r", - " @args = rs", - " @retval", - "}", - ].join("\n")) - - @SYM[func] = [sym,rdec,enc,dec] - - return sym - end - - # example: - # typealias("uint", "unsigned int") - # - def typealias(*args) - init_types() - @types.typealias(*args) - end - - # example: - # symbol "foo_value" - # symbol "foo_func", "IIP" - # - def symbol(name, ty = nil) - sym = nil - @LIBS.each{|lib| - begin - if( ty ) - sym = lib[name, ty] - else - sym = lib[name] - end - rescue - next - end - } - if( !sym ) - raise(RuntimeError, "can't find the symbol `#{name}'") - end - return sym - end - - # example: - # import("get_length", "int", ["void*", "int"]) - # - def import(name, rettype, argtypes = nil) - init_types() - init_sym() - - rty,_,rdec = @types.encode_return_type(rettype) - if( !rty ) - raise(TypeError, "unsupported type: #{rettype}") - end - ty,enc,dec = encode_argument_types(argtypes) - symty = rty + ty - - sym = symbol(name, symty) - - mname = name.dup - if( ?A <= mname[0] && mname[0] <= ?Z ) - mname[0,1] = mname[0,1].downcase - end - @SYM[mname] = [sym,rdec,enc,dec] - - module_eval [ - "def #{mname}(*args)", - " sym,rdec,enc,dec = @SYM['#{mname}']", - " args = enc.call(args) if enc", - if( $DEBUG ) - " p \"[DL] call #{mname} with \#{args.inspect}\"" - else - "" - end, - " r,rs = sym.call(*args)", - if( $DEBUG ) - " p \"[DL] retval=\#{r.inspect} args=\#{rs.inspect}\"" - else - "" - end, - " r = rdec.call(r) if rdec", - " rs = dec.call(rs) if dec", - " @retval = r", - " @args = rs", - " return @retval", - "end", - "module_function :#{mname}", - ].join("\n") - - return sym - end - - def _args_ - return @args - end - - def _retval_ - return @retval - end - - def encode_argument_types(tys) - init_types() - encty = [] - enc = nil - dec = nil - tys.each_with_index{|ty,idx| - ty,c1,c2 = @types.encode_argument_type(ty) - if( !ty ) - raise(TypeError, "unsupported type: #{ty}") - end - encty.push(ty) - if( enc ) - if( c1 ) - conv1 = enc - enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v} - end - else - if( c1 ) - enc = proc{|v| v[idx] = c1.call(v[idx]); v} - end - end - if( dec ) - if( c2 ) - conv2 = dec - dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v} - end - else - if( c2 ) - dec = proc{|v| v[idx] = c2.call(v[idx]); v} - end - end - } - return [encty.join, enc, dec] - end - end # end of Internal - include Internal - end # end of Importable -end diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb deleted file mode 100644 index 33f303fe22..0000000000 --- a/ext/dl/lib/dl/struct.rb +++ /dev/null @@ -1,149 +0,0 @@ -# -*- ruby -*- - -require 'dl' -require 'dl/import' - -module DL - module Importable - module Internal - def define_struct(contents) - init_types() - Struct.new(@types, contents) - end - alias struct define_struct - - def define_union(contents) - init_types() - Union.new(@types, contents) - end - alias union define_union - - class Memory - def initialize(ptr, names, ty, len, enc, dec) - @ptr = ptr - @names = names - @ty = ty - @len = len - @enc = enc - @dec = dec - - # define methods - @names.each{|name| - instance_eval [ - "def #{name}", - " v = @ptr[\"#{name}\"]", - " if( @len[\"#{name}\"] )", - " v = v.collect{|x| @dec[\"#{name}\"] ? @dec[\"#{name}\"].call(x) : x }", - " else", - " v = @dec[\"#{name}\"].call(v) if @dec[\"#{name}\"]", - " end", - " return v", - "end", - "def #{name}=(v)", - " if( @len[\"#{name}\"] )", - " v = v.collect{|x| @enc[\"#{name}\"] ? @enc[\"#{name}\"].call(x) : x }", - " else", - " v = @enc[\"#{name}\"].call(v) if @enc[\"#{name}\"]", - " end", - " @ptr[\"#{name}\"] = v", - " return v", - "end", - ].join("\n") - } - end - - def to_ptr - return @ptr - end - - def size - return @ptr.size - end - end - - class Struct - def initialize(types, contents) - @names = [] - @ty = {} - @len = {} - @enc = {} - @dec = {} - @size = 0 - @tys = "" - @types = types - parse(contents) - end - - def size - return @size - end - - def members - return @names - end - - # ptr must be a PtrData object. - def new(ptr) - ptr.struct!(@tys, *@names) - mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) - return mem - end - - def malloc(size = nil) - if( !size ) - size = @size - end - ptr = DL::malloc(size) - return new(ptr) - end - - def parse(contents) - contents.each{|elem| - name,ty,num,enc,dec = parse_elem(elem) - @names.push(name) - @ty[name] = ty - @len[name] = num - @enc[name] = enc - @dec[name] = dec - if( num ) - @tys += "#{ty}#{num}" - else - @tys += ty - end - } - @size = DL.sizeof(@tys) - end - - def parse_elem(elem) - elem.strip! - case elem - when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)$/ - ty = ($1 + $2).strip - name = $3 - num = nil; - when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)\[(\d+)\]$/ - ty = ($1 + $2).strip - name = $3 - num = $4.to_i - else - raise(RuntimeError, "invalid element: #{elem}") - end - ty,enc,dec = @types.encode_struct_type(ty) - if( !ty ) - raise(TypeError, "unsupported type: #{ty}") - end - return [name,ty,num,enc,dec] - end - end # class Struct - - class Union < Struct - def new - ptr = DL::malloc(@size) - ptr.union!(@tys, *@names) - mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) - return mem - end - end - end # module Internal - end # module Importable -end # module DL diff --git a/ext/dl/lib/dl/types.rb b/ext/dl/lib/dl/types.rb deleted file mode 100644 index 1144917dae..0000000000 --- a/ext/dl/lib/dl/types.rb +++ /dev/null @@ -1,245 +0,0 @@ -# -*- ruby -*- - -require 'dl' - -module DL - class Types - TYPES = [ - # FORMAT: - # ["alias name", - # "type name", encoding_method, decoding_method, for function prototypes - # "type name", encoding_method, decoding_method] for structures (not implemented) - - # for Windows - ["DWORD", "unsigned long", nil, nil, - "unsigned long", nil, nil], - ["PDWORD", "unsigned long *", nil, nil, - "unsigned long *", nil, nil], - ["WORD", "unsigned short", nil, nil, - "unsigned short", nil, nil], - ["PWORD", "unsigned int *", nil, nil, - "unsigned int *", nil, nil], - ["BYTE", "unsigned char", nil, nil, - "unsigned char", nil, nil], - ["PBYTE", "unsigned char *", nil, nil, - "unsigned char *", nil, nil], - ["BOOL", "ibool", nil, nil, - "ibool", nil, nil], - ["ATOM", "int", nil, nil, - "int", nil, nil], - ["BYTE", "unsigned char", nil, nil, - "unsigned char", nil, nil], - ["PBYTE", "unsigned char *", nil, nil, - "unsigned char *", nil, nil], - ["UINT", "unsigned int", nil, nil, - "unsigned int", nil, nil], - ["ULONG", "unsigned long", nil, nil, - "unsigned long", nil, nil], - ["UCHAR", "unsigned char", nil, nil, - "unsigned char", nil, nil], - ["HANDLE", "unsigned long", nil, nil, - "unsigned long", nil, nil], - ["PHANDLE","void*", nil, nil, - "void*", nil, nil], - ["PVOID", "void*", nil, nil, - "void*", nil, nil], - ["LPCSTR", "char*", nil, nil, - "char*", nil, nil], - ["HDC", "unsigned int", nil, nil, - "unsigned int", nil, nil], - ["HWND", "unsigned int", nil, nil, - "unsigned int", nil, nil], - - # Others - ["uint", "unsigned int", nil, nil, - "unsigned int", nil, nil], - ["u_int", "unsigned int", nil, nil, - "unsigned int", nil, nil], - ["ulong", "unsigned long", nil, nil, - "unsigned long", nil, nil], - ["u_long", "unsigned long", nil, nil, - "unsigned long", nil, nil], - - # DL::Importable primitive types - ["ibool", - "I", - proc{|v| v ? 1 : 0}, - proc{|v| (v != 0) ? true : false}, - "I", - proc{|v| v ? 1 : 0 }, - proc{|v| (v != 0) ? true : false} ], - ["cbool", - "C", - proc{|v| v ? 1 : 0}, - proc{|v| (v != 0) ? true : false}, - "C", - proc{|v,len| v ? 1 : 0}, - proc{|v,len| (v != 0) ? true : false}], - ["lbool", - "L", - proc{|v| v ? 1 : 0}, - proc{|v| (v != 0) ? true : false}, - "L", - proc{|v,len| v ? 1 : 0}, - proc{|v,len| (v != 0) ? true : false}], - ["unsigned char", - "C", - proc{|v| [v].pack("C").unpack("c")[0]}, - proc{|v| [v].pack("c").unpack("C")[0]}, - "C", - proc{|v| [v].pack("C").unpack("c")[0]}, - proc{|v| [v].pack("c").unpack("C")[0]}], - ["unsigned short", - "H", - proc{|v| [v].pack("S").unpack("s")[0]}, - proc{|v| [v].pack("s").unpack("S")[0]}, - "H", - proc{|v| [v].pack("S").unpack("s")[0]}, - proc{|v| [v].pack("s").unpack("S")[0]}], - ["unsigned int", - "I", - proc{|v| [v].pack("I").unpack("i")[0]}, - proc{|v| [v].pack("i").unpack("I")[0]}, - "I", - proc{|v| [v].pack("I").unpack("i")[0]}, - proc{|v| [v].pack("i").unpack("I")[0]}], - ["unsigned long", - "L", - proc{|v| [v].pack("L").unpack("l")[0]}, - proc{|v| [v].pack("l").unpack("L")[0]}, - "L", - proc{|v| [v].pack("L").unpack("l")[0]}, - proc{|v| [v].pack("l").unpack("L")[0]}], - ["unsigned char ref", - "c", - proc{|v| [v].pack("C").unpack("c")[0]}, - proc{|v| [v].pack("c").unpack("C")[0]}, - nil, nil, nil], - ["unsigned int ref", - "i", - proc{|v| [v].pack("I").unpack("i")[0]}, - proc{|v| [v].pack("i").unpack("I")[0]}, - nil, nil, nil], - ["unsigned long ref", - "l", - proc{|v| [v].pack("L").unpack("l")[0]}, - proc{|v| [v].pack("l").unpack("L")[0]}, - nil, nil, nil], - ["char ref", "c", nil, nil, - nil, nil, nil], - ["short ref", "h", nil, nil, - nil, nil, nil], - ["int ref", "i", nil, nil, - nil, nil, nil], - ["long ref", "l", nil, nil, - nil, nil, nil], - ["float ref", "f", nil, nil, - nil, nil, nil], - ["double ref","d", nil, nil, - nil, nil, nil], - ["char", "C", nil, nil, - "C", nil, nil], - ["short", "H", nil, nil, - "H", nil, nil], - ["int", "I", nil, nil, - "I", nil, nil], - ["long", "L", nil, nil, - "L", nil, nil], - ["float", "F", nil, nil, - "F", nil, nil], - ["double", "D", nil, nil, - "D", nil, nil], - [/^char\s*\*$/,"s",nil, nil, - "S",nil, nil], - [/^const char\s*\*$/,"S",nil, nil, - "S",nil, nil], - [/^.+\*$/, "P", nil, nil, - "P", nil, nil], - [/^.+\[\]$/, "a", nil, nil, - "a", nil, nil], - ["void", "0", nil, nil, - nil, nil, nil], - ] - - def initialize - init_types() - end - - def typealias(ty1, ty2, enc=nil, dec=nil, ty3=nil, senc=nil, sdec=nil) - @TYDEFS.unshift([ty1, ty2, enc, dec, ty3, senc, sdec]) - end - - def init_types - @TYDEFS = TYPES.dup - end - - def encode_argument_type(alias_type) - proc_encode = nil - proc_decode = nil - @TYDEFS.each{|aty,ty,enc,dec,_,_,_| - if( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) ) - alias_type = alias_type.gsub(aty,ty) if ty - alias_type.strip! if alias_type - if( proc_encode ) - if( enc ) - conv1 = proc_encode - proc_encode = proc{|v| enc.call(conv1.call(v))} - end - else - if( enc ) - proc_encode = enc - end - end - if( proc_decode ) - if( dec ) - conv2 = proc_decode - proc_decode = proc{|v| dec.call(conv2.call(v))} - end - else - if( dec ) - proc_decode = dec - end - end - end - } - return [alias_type, proc_encode, proc_decode] - end - - def encode_return_type(ty) - ty, enc, dec = encode_argument_type(ty) - return [ty, enc, dec] - end - - def encode_struct_type(alias_type) - proc_encode = nil - proc_decode = nil - @TYDEFS.each{|aty,_,_,_,ty,enc,dec| - if( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) ) - alias_type = alias_type.gsub(aty,ty) if ty - alias_type.strip! if alias_type - if( proc_encode ) - if( enc ) - conv1 = proc_encode - proc_encode = proc{|v| enc.call(conv1.call(v))} - end - else - if( enc ) - proc_encode = enc - end - end - if( proc_decode ) - if( dec ) - conv2 = proc_decode - proc_decode = proc{|v| dec.call(conv2.call(v))} - end - else - if( dec ) - proc_decode = dec - end - end - end - } - return [alias_type, proc_encode, proc_decode] - end - end # end of Types -end diff --git a/ext/dl/lib/dl/win32.rb b/ext/dl/lib/dl/win32.rb deleted file mode 100644 index 92f473d392..0000000000 --- a/ext/dl/lib/dl/win32.rb +++ /dev/null @@ -1,25 +0,0 @@ -# -*- ruby -*- - -require 'dl' - -class Win32API - DLL = {} - - def initialize(dllname, func, import, export = "0") - prototype = (export + import.to_s).tr("VPpNnLlIi", "0SSI") - handle = DLL[dllname] ||= DL::Handle.new(dllname) - @sym = handle.sym(func, prototype) - end - - def call(*args) - import = @sym.proto.split("", 2)[1] - args.each_with_index do |x, i| - args[i] = nil if x == 0 and import[i] == ?S - args[i], = [x].pack("I").unpack("i") if import[i] == ?I - end - ret, = @sym.call(*args) - return ret || 0 - end - - alias Call call -end diff --git a/ext/dl/mkcall.rb b/ext/dl/mkcall.rb deleted file mode 100644 index 6a85570152..0000000000 --- a/ext/dl/mkcall.rb +++ /dev/null @@ -1,62 +0,0 @@ -# -*- ruby -*- - -require 'mkmf' -$:.unshift File.dirname(__FILE__) -require 'type' -require 'dlconfig' - -def output_arg(x,i) - "args[#{i}].#{DLTYPE[x][:stmem]}" -end - -def output_args(types) - t = [] - types[1..-1].each_with_index{|x,i| t.push(output_arg(x,i))} - t.join(",") -end - -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 - -def output_case(types) - num = types2num(types) - callfunc_stm = output_callfunc(types) -<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 - -DLTYPE.keys.sort.each{|t| - for n in 0..(MAX_CALLBACK - 1) - print(mkfunc(t, n, 15), "\n\n") - end -} diff --git a/ext/dl/mkcbtable.rb b/ext/dl/mkcbtable.rb deleted file mode 100644 index 165c4bdc88..0000000000 --- a/ext/dl/mkcbtable.rb +++ /dev/null @@ -1,18 +0,0 @@ -# -*- ruby -*- - -require 'mkmf' -$:.unshift File.dirname(__FILE__) -require 'type' -require 'dlconfig' - -def mktable(rettype, fnum, argc) - code = - "rb_dl_callback_table[#{rettype}][#{fnum}] = &rb_dl_callback_func_#{rettype.to_s}_#{fnum};" - return code -end - -DLTYPE.keys.sort.each{|t| - for n in 0..(MAX_CALLBACK - 1) - print(mktable(t, n, 15), "\n") - end -} diff --git a/ext/dl/ptr.c b/ext/dl/ptr.c deleted file mode 100644 index fba370b572..0000000000 --- a/ext/dl/ptr.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- - * $Id$ - */ - -#include -#include -#include -#include "dl.h" - -VALUE rb_cDLPtrData; -VALUE rb_mDLMemorySpace; -static st_table *DLMemoryTable; -static int finalized; - -#ifndef T_SYMBOL -# define T_SYMBOL T_FIXNUM -#endif - -static void -free_memtbl(void *ptr) -{ - if (!DLMemoryTable) return; - if (DLMemoryTable->num_entries) { - finalized = 1; - } - else { - st_free_table(DLMemoryTable); - DLMemoryTable = 0; - } -} - -static void -rb_dlmem_delete(void *ptr) -{ - st_data_t key = (st_data_t)ptr; - - if (!DLMemoryTable) return; - st_delete(DLMemoryTable, &key, 0); - if (finalized && !DLMemoryTable->num_entries) { - st_free_table(DLMemoryTable); - DLMemoryTable = 0; - } -} - -static void -rb_dlmem_aset(void *ptr, VALUE obj) -{ - st_data_t val; - if (!st_lookup(DLMemoryTable, (st_data_t)ptr, &val) || (VALUE)val != obj) { - st_add_direct(DLMemoryTable, (st_data_t)ptr, (st_data_t)obj); - } -} - -static VALUE -rb_dlmem_aref(void *ptr) -{ - st_data_t val; - - if (!st_lookup(DLMemoryTable, (st_data_t)ptr, &val)) - return Qnil; - return (VALUE)val; -} - -void -dlptr_free(struct ptr_data *data) -{ - if (data->ptr) { - DEBUG_CODE({ - printf("dlptr_free(): removing the pointer `0x%x' from the MemorySpace\n", - data->ptr); - }); - rb_dlmem_delete(data->ptr); - if (data->free) { - DEBUG_CODE({ - printf("dlptr_free(): 0x%x(data->ptr:0x%x)\n",data->free,data->ptr); - }); - (*(data->free))(data->ptr); - } - } - if (data->stype) dlfree(data->stype); - if (data->ssize) dlfree(data->ssize); - if (data->ids) dlfree(data->ids); - dlfree(data); -} - -void -dlptr_init(VALUE val) -{ - struct ptr_data *data; - - Data_Get_Struct(val, struct ptr_data, data); - DEBUG_CODE({ - printf("dlptr_init(): add the pointer `0x%x' to the MemorySpace\n", - data->ptr); - }); - rb_dlmem_aset(data->ptr, val); - OBJ_TAINT(val); -} - -VALUE -rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func) -{ - struct ptr_data *data; - VALUE val; - - rb_secure(4); - if (ptr) { - val = rb_dlmem_aref(ptr); - if (NIL_P(val)) { - val = Data_Make_Struct(klass, struct ptr_data, - 0, dlptr_free, data); - data->ptr = ptr; - data->free = func; - data->ctype = DLPTR_CTYPE_UNKNOWN; - data->stype = NULL; - data->ssize = NULL; - data->slen = 0; - data->size = size; - data->ids = NULL; - data->ids_num = 0; - dlptr_init(val); - } - else{ - if (func) { - Data_Get_Struct(val, struct ptr_data, data); - data->free = func; - } - } - } - else{ - val = Qnil; - } - - return val; -} - -VALUE -rb_dlptr_new(void *ptr, long size, freefunc_t func) -{ - return rb_dlptr_new2(rb_cDLPtrData, ptr, size, func); -} - -VALUE -rb_dlptr_malloc(long size, freefunc_t func) -{ - void *ptr; - - rb_secure(4); - ptr = dlmalloc((size_t)size); - memset(ptr,0,(size_t)size); - return rb_dlptr_new(ptr, size, func); -} - -void * -rb_dlptr2cptr(VALUE val) -{ - struct ptr_data *data; - void *ptr; - - if (rb_obj_is_kind_of(val, rb_cDLPtrData)) { - Data_Get_Struct(val, struct ptr_data, data); - ptr = data->ptr; - } - else if (NIL_P(val)) { - ptr = NULL; - } - else{ - rb_raise(rb_eTypeError, "DL::PtrData was expected"); - } - - return ptr; -} - -static VALUE -rb_dlptr_s_allocate(VALUE klass) -{ - VALUE obj; - struct ptr_data *data; - - rb_secure(4); - obj = Data_Make_Struct(klass, struct ptr_data, 0, dlptr_free, data); - data->ptr = 0; - data->free = 0; - data->ctype = DLPTR_CTYPE_UNKNOWN; - data->stype = NULL; - data->ssize = NULL; - data->slen = 0; - data->size = 0; - data->ids = NULL; - data->ids_num = 0; - - return obj; -} - -static VALUE -rb_dlptr_initialize(int argc, VALUE argv[], VALUE self) -{ - VALUE ptr, sym, size; - struct ptr_data *data; - void *p = NULL; - freefunc_t f = NULL; - long s = 0; - - rb_secure(4); - switch (rb_scan_args(argc, argv, "12", &ptr, &size, &sym)) { - case 1: - p = (void*)(DLNUM2LONG(rb_Integer(ptr))); - break; - case 2: - p = (void*)(DLNUM2LONG(rb_Integer(ptr))); - s = DLNUM2LONG(size); - break; - case 3: - p = (void*)(DLNUM2LONG(rb_Integer(ptr))); - s = DLNUM2LONG(size); - f = rb_dlsym2csym(sym); - break; - default: - rb_bug("rb_dlptr_initialize"); - } - - if (p) { - Data_Get_Struct(self, struct ptr_data, data); - if (data->ptr) { - rb_dlmem_delete(data->ptr); - if (data->free) { - /* Free previous memory. Use of inappropriate initialize may cause SEGV. */ - (*data->free)(data->ptr); - } - } - data->ptr = p; - data->size = s; - data->free = f; - if (p) { - if (NIL_P(rb_dlmem_aref(p))) rb_dlmem_aset(p, self); - } - } - - return Qnil; -} - -static VALUE -rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass) -{ - VALUE size, sym, obj; - int s; - freefunc_t f = NULL; - - switch (rb_scan_args(argc, argv, "11", &size, &sym)) { - case 1: - s = NUM2INT(size); - break; - case 2: - s = NUM2INT(size); - f = rb_dlsym2csym(sym); - break; - default: - rb_bug("rb_dlptr_s_malloc"); - } - - obj = rb_dlptr_malloc(s,f); - - return obj; -} - -VALUE -rb_dlptr_to_i(VALUE self) -{ - struct ptr_data *data; - - Data_Get_Struct(self, struct ptr_data, data); - return DLLONG2NUM(data->ptr); -} - -VALUE -rb_dlptr_ptr(VALUE self) -{ - struct ptr_data *data; - - Data_Get_Struct(self, struct ptr_data, data); - return rb_dlptr_new(*((void**)(data->ptr)),0,0); -} - -VALUE -rb_dlptr_ref(VALUE self) -{ - struct ptr_data *data; - - Data_Get_Struct(self, struct ptr_data, data); - return rb_dlptr_new(&(data->ptr),0,0); -} - -VALUE -rb_dlptr_null_p(VALUE self) -{ - struct ptr_data *data; - - Data_Get_Struct(self, struct ptr_data, data); - return data->ptr ? Qfalse : Qtrue; -} - -VALUE -rb_dlptr_free_set(VALUE self, VALUE val) -{ - struct ptr_data *data; - - Data_Get_Struct(self, struct ptr_data, data); - - data->free = DLFREEFUNC(rb_dlsym2csym(val)); - - return Qnil; -} - -VALUE -rb_dlptr_free_get(VALUE self) -{ - struct ptr_data *pdata; - - Data_Get_Struct(self, struct ptr_data, pdata); - - return rb_dlsym_new(pdata->free,"(free)","0P"); -} - -VALUE -rb_dlptr_to_array(int argc, VALUE argv[], VALUE self) -{ - struct ptr_data *data; - int n; - int i; - int t; - VALUE ary; - VALUE type, size; - - Data_Get_Struct(self, struct ptr_data, data); - - switch (rb_scan_args(argc, argv, "11", &type, &size)) { - case 2: - t = StringValuePtr(type)[0]; - n = NUM2INT(size); - break; - case 1: - t = StringValuePtr(type)[0]; - switch (t) { - case 'C': - n = data->size; - break; - case 'H': - n = data->size / sizeof(short); - break; - case 'I': - n = data->size / sizeof(int); - break; - case 'L': - n = data->size / sizeof(long); - break; - case 'F': - n = data->size / sizeof(float); - break; - case 'D': - n = data->size / sizeof(double); - break; - case 'P': case 'p': - n = data->size / sizeof(void*); - break; - case 'S': case 's': - for (n=0; ((void**)(data->ptr))[n]; n++) {}; - break; - default: - n = 0; - } - break; - default: - rb_bug("rb_dlptr_to_array"); - } - - ary = rb_ary_new(); - - for (i=0; i < n; i++) { - switch (t) { - case 'C': - rb_ary_push(ary, INT2NUM(((char*)(data->ptr))[i])); - break; - case 'H': - rb_ary_push(ary, INT2NUM(((short*)(data->ptr))[i])); - break; - case 'I': - rb_ary_push(ary, INT2NUM(((int*)(data->ptr))[i])); - break; - case 'L': - rb_ary_push(ary, DLLONG2NUM(((long*)(data->ptr))[i])); - break; - case 'D': - rb_ary_push(ary, rb_float_new(((double*)(data->ptr))[i])); - break; - case 'F': - rb_ary_push(ary, rb_float_new(((float*)(data->ptr))[i])); - break; - case 'S': - { - char *str = ((char**)(data->ptr))[i]; - if (str) { - rb_ary_push(ary, rb_tainted_str_new2(str)); - } - else{ - rb_ary_push(ary, Qnil); - } - } - break; - case 's': - { - char *str = ((char**)(data->ptr))[i]; - if (str) { - rb_ary_push(ary, rb_tainted_str_new2(str)); - xfree(str); - } - else{ - rb_ary_push(ary, Qnil); - } - } - break; - case 'P': - rb_ary_push(ary, rb_dlptr_new(((void**)(data->ptr))[i],0,0)); - break; - case 'p': - rb_ary_push(ary, - rb_dlptr_new(((void**)(data->ptr))[i],0,dlfree)); - break; - } - } - - return ary; -} - - -VALUE -rb_dlptr_to_s(int argc, VALUE argv[], VALUE self) -{ - struct ptr_data *data; - VALUE arg1, val; - int len; - - Data_Get_Struct(self, struct ptr_data, data); - switch (rb_scan_args(argc, argv, "01", &arg1)) { - case 0: - val = rb_tainted_str_new2((char*)(data->ptr)); - break; - case 1: - len = NUM2INT(arg1); - val = rb_tainted_str_new((char*)(data->ptr), len); - break; - default: - rb_bug("rb_dlptr_to_s"); - } - - return val; -} - -VALUE -rb_dlptr_to_str(int argc, VALUE argv[], VALUE self) -{ - struct ptr_data *data; - VALUE arg1, val; - int len; - - Data_Get_Struct(self, struct ptr_data, data); - switch (rb_scan_args(argc, argv, "01", &arg1)) { - case 0: - val = rb_tainted_str_new((char*)(data->ptr),data->size); - break; - case 1: - len = NUM2INT(arg1); - val = rb_tainted_str_new((char*)(data->ptr), len); - break; - default: - rb_bug("rb_dlptr_to_str"); - } - - return val; -} - -VALUE -rb_dlptr_inspect(VALUE self) -{ - struct ptr_data *data; - char str[1024]; - - Data_Get_Struct(self, struct ptr_data, data); - snprintf(str, 1023, "#<%s:0x%p ptr=0x%p size=%ld free=0x%p>", - rb_class2name(CLASS_OF(self)), data, data->ptr, data->size, data->free); - return rb_str_new2(str); -} - -VALUE -rb_dlptr_eql(VALUE self, VALUE other) -{ - void *ptr1, *ptr2; - ptr1 = rb_dlptr2cptr(self); - ptr2 = rb_dlptr2cptr(other); - - return ptr1 == ptr2 ? Qtrue : Qfalse; -} - -VALUE -rb_dlptr_cmp(VALUE self, VALUE other) -{ - void *ptr1, *ptr2; - ptr1 = rb_dlptr2cptr(self); - ptr2 = rb_dlptr2cptr(other); - return DLLONG2NUM((long)ptr1 - (long)ptr2); -} - -VALUE -rb_dlptr_plus(VALUE self, VALUE other) -{ - void *ptr; - long num, size; - - ptr = rb_dlptr2cptr(self); - size = RDLPTR(self)->size; - num = DLNUM2LONG(other); - return rb_dlptr_new((char *)ptr + num, size - num, 0); -} - -VALUE -rb_dlptr_minus(VALUE self, VALUE other) -{ - void *ptr; - long num, size; - - ptr = rb_dlptr2cptr(self); - size = RDLPTR(self)->size; - num = DLNUM2LONG(other); - return rb_dlptr_new((char *)ptr - num, size + num, 0); -} - -VALUE -rb_dlptr_define_data_type(int argc, VALUE argv[], VALUE self) -{ - VALUE data_type, type, rest, vid; - struct ptr_data *data; - int i, t, num; - char *ctype; - - rb_scan_args(argc, argv, "11*", &data_type, &type, &rest); - Data_Get_Struct(self, struct ptr_data, data); - - if (NIL_P(type)) { - if (NUM2INT(data_type) == DLPTR_CTYPE_UNKNOWN) { - data->ctype = DLPTR_CTYPE_UNKNOWN; - data->slen = 0; - data->ids_num = 0; - if (data->stype) { - dlfree(data->stype); - data->stype = NULL; - } - if (data->ids) { - dlfree(data->ids); - data->ids = NULL; - } - return Qnil; - } - else{ - rb_raise(rb_eArgError, "wrong arguments"); - } - } - - t = NUM2INT(data_type); - StringValue(type); - Check_Type(rest, T_ARRAY); - num = RARRAY(rest)->len; - for (i=0; ictype = t; - data->slen = num; - data->ids_num = num; - if (data->stype) dlfree(data->stype); - data->stype = (char*)dlmalloc(sizeof(char) * num); - if (data->ssize) dlfree(data->ssize); - data->ssize = (int*)dlmalloc(sizeof(int) * num); - if (data->ids) dlfree(data->ids); - data->ids = (ID*)dlmalloc(sizeof(ID) * data->ids_num); - - ctype = StringValuePtr(type); - for (i=0; iids[i] = rb_to_id(vid); - data->stype[i] = *ctype; - ctype ++; - if (ISDIGIT(*ctype)) { - char *p, *d; - for (p=ctype; ISDIGIT(*p); p++) ; - d = ALLOCA_N(char, p - ctype + 1); - strncpy(d, ctype, p - ctype); - d[p - ctype] = '\0'; - data->ssize[i] = atoi(d); - ctype = p; - } - else{ - data->ssize[i] = 1; - } - } - - if (*ctype) { - rb_raise(rb_eArgError, "too few/many arguments"); - } - - if (!data->size) - data->size = dlsizeof(RSTRING(type)->ptr); - - return Qnil; -} - -VALUE -rb_dlptr_define_struct(int argc, VALUE argv[], VALUE self) -{ - VALUE *pass_argv; - int pass_argc, i; - - pass_argc = argc + 1; - pass_argv = ALLOCA_N(VALUE, pass_argc); - pass_argv[0] = INT2FIX(DLPTR_CTYPE_STRUCT); - for (i=1; istype) - return rb_assoc_new(INT2FIX(data->ctype), - rb_tainted_str_new(data->stype, data->slen)); - else - return rb_assoc_new(INT2FIX(data->ctype), Qnil); -} - -static VALUE -cary2ary(void *ptr, char t, int len) -{ - VALUE ary; - VALUE elem; - int i; - - if (len < 1) - return Qnil; - - if (len == 1) { - switch (t) { - case 'I': - elem = INT2NUM(*((int*)ptr)); - ptr = (char *)ptr + sizeof(int); - break; - case 'L': - elem = DLLONG2NUM(*((long*)ptr)); - ptr = (char *)ptr + sizeof(long); - break; - case 'P': - case 'S': - elem = rb_dlptr_new(*((void**)ptr),0, 0); - ptr = (char *)ptr + sizeof(void*); - break; - case 'F': - elem = rb_float_new(*((float*)ptr)); - ptr = (char *)ptr + sizeof(float); - break; - case 'D': - elem = rb_float_new(*((double*)ptr)); - ptr = (char *)ptr + sizeof(double); - break; - case 'C': - elem = INT2NUM(*((char*)ptr)); - ptr = (char *)ptr + sizeof(char); - break; - case 'H': - elem = INT2NUM(*((short*)ptr)); - ptr = (char *)ptr + sizeof(short); - break; - default: - rb_raise(rb_eDLTypeError, "cary2ary: unsupported type '%c'", t); - } - return elem; - } - - ary = rb_ary_new(); - for (i=0; i < len; i++) { - switch (t) { - case 'I': - elem = INT2NUM(*((int*)ptr)); - ptr = (char *)ptr + sizeof(int); - break; - case 'L': - elem = DLLONG2NUM(*((long*)ptr)); - ptr = (char *)ptr + sizeof(long); - break; - case 'P': - case 'S': - elem = rb_dlptr_new(*((void**)ptr), 0, 0); - ptr = (char *)ptr + sizeof(void*); - break; - case 'F': - elem = rb_float_new(*((float*)ptr)); - ptr = (char *)ptr + sizeof(float); - break; - case 'D': - elem = rb_float_new(*((float*)ptr)); - ptr = (char *)ptr + sizeof(double); - break; - case 'C': - elem = INT2NUM(*((char*)ptr)); - ptr = (char *)ptr + sizeof(char); - break; - case 'H': - elem = INT2NUM(*((short*)ptr)); - ptr = (char *)ptr + sizeof(short); - break; - default: - rb_raise(rb_eDLTypeError, "cary2ary: unsupported type '%c'", t); - } - rb_ary_push(ary, elem); - } - - return ary; -} - -VALUE -rb_dlptr_aref(int argc, VALUE argv[], VALUE self) -{ - VALUE key = Qnil, num = Qnil; - ID id; - struct ptr_data *data; - int i; - int offset; - - if (rb_scan_args(argc, argv, "11", &key, &num) == 1) { - num = INT2NUM(0); - } - - if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) { - VALUE pass[1]; - pass[0] = num; - return rb_dlptr_to_str(1, pass, rb_dlptr_plus(self, key)); - } - rb_to_id(key); - if (! (TYPE(key) == T_STRING || TYPE(key) == T_SYMBOL)) { - rb_raise(rb_eTypeError, "the key must be a string or symbol"); - } - - id = rb_to_id(key); - Data_Get_Struct(self, struct ptr_data, data); - offset = 0; - switch (data->ctype) { - case DLPTR_CTYPE_STRUCT: - for (i=0; i < data->ids_num; i++) { - if (data->ids[i] == id) { - switch (data->stype[i]) { - case 'I': - DLALIGN(data->ptr,offset,INT_ALIGN); - break; - case 'L': - DLALIGN(data->ptr,offset,LONG_ALIGN); - break; - case 'P': - case 'S': - DLALIGN(data->ptr,offset,VOIDP_ALIGN); - break; - case 'F': - DLALIGN(data->ptr,offset,FLOAT_ALIGN); - break; - case 'D': - DLALIGN(data->ptr,offset,DOUBLE_ALIGN); - break; - case 'C': - break; - case 'H': - DLALIGN(data->ptr,offset,SHORT_ALIGN); - break; - default: - rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]); - } - return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]); - } - switch (data->stype[i]) { - case 'I': - offset += sizeof(int) * data->ssize[i]; - break; - case 'L': - offset += sizeof(long) * data->ssize[i]; - break; - case 'P': - case 'S': - offset += sizeof(void*) * data->ssize[i]; - break; - case 'F': - offset += sizeof(float) * data->ssize[i]; - break; - case 'D': - offset += sizeof(double) * data->ssize[i]; - break; - case 'C': - offset += sizeof(char) * data->ssize[i]; - break; - case 'H': - offset += sizeof(short) * data->ssize[i]; - break; - default: - rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]); - } - } - break; - case DLPTR_CTYPE_UNION: - for (i=0; i < data->ids_num; i++) { - if (data->ids[i] == id) { - return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]); - } - } - break; - } /* end of switch */ - - rb_raise(rb_eNameError, "undefined key `%s' for %s", - rb_id2name(id), rb_class2name(CLASS_OF(self))); - - return Qnil; -} - -static void * -ary2cary(char t, VALUE val, long *size) -{ - void *ptr; - - if (TYPE(val) == T_ARRAY) { - ptr = rb_ary2cary(t, val, size); - } - else{ - ptr = rb_ary2cary(t, rb_ary_new3(1, val), size); - } - return ptr; -} - -VALUE -rb_dlptr_aset(int argc, VALUE argv[], VALUE self) -{ - VALUE key = Qnil, num = Qnil, val = Qnil; - ID id; - struct ptr_data *data; - int i; - int offset; - long memsize; - void *memimg; - - rb_secure(4); - switch (rb_scan_args(argc, argv, "21", &key, &num, &val)) { - case 2: - val = num; - num = Qnil; - break; - } - - if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) { - void *dst, *src; - long len; - - StringValue(val); - Data_Get_Struct(self, struct ptr_data, data); - dst = (void*)((long)(data->ptr) + DLNUM2LONG(key)); - src = RSTRING(val)->ptr; - len = RSTRING(val)->len; - if (NIL_P(num)) { - memcpy(dst, src, len); - } - else{ - long n = NUM2INT(num); - memcpy(dst, src, n < len ? n : len); - if (n > len) MEMZERO((char*)dst + len, char, n - len); - } - return val; - } - - id = rb_to_id(key); - Data_Get_Struct(self, struct ptr_data, data); - switch (data->ctype) { - case DLPTR_CTYPE_STRUCT: - offset = 0; - for (i=0; i < data->ids_num; i++) { - if (data->ids[i] == id) { - switch (data->stype[i]) { - case 'I': - DLALIGN(data->ptr,offset,INT_ALIGN); - break; - case 'L': - DLALIGN(data->ptr,offset,LONG_ALIGN); - break; - case 'P': - case 'S': - DLALIGN(data->ptr,offset,VOIDP_ALIGN); - break; - case 'D': - DLALIGN(data->ptr,offset,DOUBLE_ALIGN); - break; - case 'F': - DLALIGN(data->ptr,offset,FLOAT_ALIGN); - break; - case 'C': - break; - case 'H': - DLALIGN(data->ptr,offset,SHORT_ALIGN); - break; - default: - rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]); - } - memimg = ary2cary(data->stype[i], val, &memsize); - memcpy((char *)data->ptr + offset, memimg, memsize); - return val; - } - switch (data->stype[i]) { - case 'I': - case 'i': - offset += sizeof(int) * data->ssize[i]; - break; - case 'L': - case 'l': - offset += sizeof(long) * data->ssize[i]; - break; - case 'P': - case 'p': - case 'S': - case 's': - offset += sizeof(void*) * data->ssize[i]; - break; - case 'D': - case 'd': - offset += sizeof(double) * data->ssize[i]; - break; - case 'F': - case 'f': - offset += sizeof(float) * data->ssize[i]; - break; - case 'C': - case 'c': - offset += sizeof(char) * data->ssize[i]; - break; - case 'H': - case 'h': - offset += sizeof(short) * data->ssize[i]; - break; - default: - rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]); - } - } - return val; - /* break; */ - case DLPTR_CTYPE_UNION: - for (i=0; i < data->ids_num; i++) { - if (data->ids[i] == id) { - switch (data->stype[i]) { - case 'I': case 'i': - memsize = sizeof(int) * data->ssize[i]; - break; - case 'L': case 'l': - memsize = sizeof(long) * data->ssize[i]; - break; - case 'P': case 'p': - case 'S': case 's': - memsize = sizeof(void*) * data->ssize[i]; - break; - case 'F': case 'f': - memsize = sizeof(float) * data->ssize[i]; - break; - case 'D': case 'd': - memsize = sizeof(double) * data->ssize[i]; - break; - case 'C': case 'c': - memsize = sizeof(char) * data->ssize[i]; - break; - case 'H': case 'h': - memsize = sizeof(short) * data->ssize[i]; - break; - default: - rb_raise(rb_eDLTypeError, "unsupported type '%c'", data->stype[i]); - } - memimg = ary2cary(data->stype[i], val, NULL); - memcpy(data->ptr, memimg, memsize); - } - } - return val; - /* break; */ - } - - rb_raise(rb_eNameError, "undefined key `%s' for %s", - rb_id2name(id), rb_class2name(CLASS_OF(self))); - - return Qnil; -} - -VALUE -rb_dlptr_size(int argc, VALUE argv[], VALUE self) -{ - VALUE size; - - if (rb_scan_args(argc, argv, "01", &size) == 0){ - return DLLONG2NUM(RDLPTR(self)->size); - } - else{ - RDLPTR(self)->size = DLNUM2LONG(size); - return size; - } -} - -static int -dlmem_each_i(st_data_t key, st_data_t val, st_data_t arg) -{ - rb_yield_values(DLLONG2NUM(key), (VALUE)val); - return ST_CONTINUE; -} - -VALUE -rb_dlmem_each(VALUE self) -{ - st_foreach(DLMemoryTable, dlmem_each_i, 0); - return Qnil; -} - -void -Init_dlptr() -{ - rb_cDLPtrData = rb_define_class_under(rb_mDL, "PtrData", rb_cObject); - rb_define_alloc_func(rb_cDLPtrData, rb_dlptr_s_allocate); - rb_define_singleton_method(rb_cDLPtrData, "malloc", rb_dlptr_s_malloc, -1); - rb_define_method(rb_cDLPtrData, "initialize", rb_dlptr_initialize, -1); - rb_define_method(rb_cDLPtrData, "free=", rb_dlptr_free_set, 1); - rb_define_method(rb_cDLPtrData, "free", rb_dlptr_free_get, 0); - rb_define_method(rb_cDLPtrData, "to_i", rb_dlptr_to_i, 0); - rb_define_method(rb_cDLPtrData, "ptr", rb_dlptr_ptr, 0); - rb_define_method(rb_cDLPtrData, "+@", rb_dlptr_ptr, 0); - rb_define_method(rb_cDLPtrData, "ref", rb_dlptr_ref, 0); - rb_define_method(rb_cDLPtrData, "-@", rb_dlptr_ref, 0); - rb_define_method(rb_cDLPtrData, "null?", rb_dlptr_null_p, 0); - rb_define_method(rb_cDLPtrData, "to_a", rb_dlptr_to_array, -1); - rb_define_method(rb_cDLPtrData, "to_s", rb_dlptr_to_s, -1); - rb_define_method(rb_cDLPtrData, "to_str", rb_dlptr_to_str, -1); - rb_define_method(rb_cDLPtrData, "inspect", rb_dlptr_inspect, 0); - rb_define_method(rb_cDLPtrData, "<=>", rb_dlptr_cmp, 1); - rb_define_method(rb_cDLPtrData, "==", rb_dlptr_eql, 1); - rb_define_method(rb_cDLPtrData, "eql?", rb_dlptr_eql, 1); - rb_define_method(rb_cDLPtrData, "+", rb_dlptr_plus, 1); - rb_define_method(rb_cDLPtrData, "-", rb_dlptr_minus, 1); - rb_define_method(rb_cDLPtrData, "define_data_type", - rb_dlptr_define_data_type, -1); - rb_define_method(rb_cDLPtrData, "struct!", rb_dlptr_define_struct, -1); - rb_define_method(rb_cDLPtrData, "union!", rb_dlptr_define_union, -1); - rb_define_method(rb_cDLPtrData, "data_type", rb_dlptr_get_data_type, 0); - rb_define_method(rb_cDLPtrData, "[]", rb_dlptr_aref, -1); - rb_define_method(rb_cDLPtrData, "[]=", rb_dlptr_aset, -1); - rb_define_method(rb_cDLPtrData, "size", rb_dlptr_size, -1); - rb_define_method(rb_cDLPtrData, "size=", rb_dlptr_size, -1); - - rb_mDLMemorySpace = rb_define_module_under(rb_mDL, "MemorySpace"); - rb_extend_object(rb_mDLMemorySpace, rb_mEnumerable); - DLMemoryTable = st_init_numtable(); - rb_define_const(rb_mDLMemorySpace, "MemoryTable", - Data_Wrap_Struct(rb_cData, 0, free_memtbl, DLMemoryTable)); - rb_define_module_function(rb_mDLMemorySpace, "each", rb_dlmem_each, 0); -} diff --git a/ext/dl/sample/c++sample.C b/ext/dl/sample/c++sample.C deleted file mode 100644 index d083d337a7..0000000000 --- a/ext/dl/sample/c++sample.C +++ /dev/null @@ -1,35 +0,0 @@ -#include - -class Person { -private: - const char *name; - int age; - -public: - Person(const char *name, int age); - const char * get_name(); - int get_age(); - void set_age(int i); -}; - -Person::Person(const char *name, int age) - : name(name), age(age) -{ - /* empty */ -} - -const char * -Person::get_name() -{ - return name; -} - -int -Person::get_age(){ - return age; -} - -void -Person::set_age(int i){ - age = i; -} diff --git a/ext/dl/sample/c++sample.rb b/ext/dl/sample/c++sample.rb deleted file mode 100644 index 29887df845..0000000000 --- a/ext/dl/sample/c++sample.rb +++ /dev/null @@ -1,60 +0,0 @@ -=begin - This script shows how to deal with C++ classes using Ruby/DL. - You must build a dynamic loadable library using "c++sample.C" - to run this script as follows: - $ g++ -o libsample.so -shared c++sample.C -=end - -require 'dl' -require 'dl/import' -require 'dl/struct' - -# Give a name of dynamic loadable library -LIBNAME = ARGV[0] || "libsample.so" - -class Person - module Core - extend DL::Importable - - dlload LIBNAME - - # mangled symbol names - extern "void __6PersonPCci(void *, const char *, int)" - extern "const char *get_name__6Person(void *)" - extern "int get_age__6Person(void *)" - extern "void set_age__6Personi(void *, int)" - - Data = struct [ - "char *name", - "int age", - ] - end - - def initialize(name, age) - @ptr = Core::Data.alloc - Core::__6PersonPCci(@ptr, name, age) - end - - def get_name() - str = Core::get_name__6Person(@ptr) - if( str ) - str.to_s - else - nil - end - end - - def get_age() - Core::get_age__6Person(@ptr) - end - - def set_age(age) - Core::set_age__6Personi(@ptr, age) - end -end - -obj = Person.new("ttate", 1) -p obj.get_name() -p obj.get_age() -obj.set_age(10) -p obj.get_age() diff --git a/ext/dl/sample/drives.rb b/ext/dl/sample/drives.rb deleted file mode 100644 index 8a590404b1..0000000000 --- a/ext/dl/sample/drives.rb +++ /dev/null @@ -1,70 +0,0 @@ -# -*- ruby -*- -# drives.rb -- find existing drives and show the drive type. - -require 'dl' -require 'dl/import' - -module Kernel32 - extend DL::Importable - - dlload "kernel32" - - extern "long GetLogicalDrives()" - extern "int GetDriveType(char*)" - extern "long GetDiskFreeSpace(char*, long ref, long ref, long ref, long ref)" -end - -include Kernel32 - -buff = Kernel32.getLogicalDrives() - -i = 0 -ds = [] -while( i < 26 ) - mask = (1 << i) - if( buff & mask > 0 ) - ds.push((65+i).chr) - end - i += 1 -end - -=begin -From the cygwin's /usr/include/w32api/winbase.h: -#define DRIVE_UNKNOWN 0 -#define DRIVE_NO_ROOT_DIR 1 -#define DRIVE_REMOVABLE 2 -#define DRIVE_FIXED 3 -#define DRIVE_REMOTE 4 -#define DRIVE_CDROM 5 -#define DRIVE_RAMDISK 6 -=end - -types = [ - "unknown", - "no root dir", - "Removable", - "Fixed", - "Remote", - "CDROM", - "RAM", -] -print("Drive : Type (Free Space/Available Space)\n") -ds.each{|d| - t = Kernel32.getDriveType(d + ":\\") - Kernel32.getDiskFreeSpace(d + ":\\", 0, 0, 0, 0) - _,sec_per_clus,byte_per_sec,free_clus,total_clus = Kernel32._args_ - fbytes = sec_per_clus * byte_per_sec * free_clus - tbytes = sec_per_clus * byte_per_sec * total_clus - unit = "B" - if( fbytes > 1024 && tbytes > 1024 ) - fbytes = fbytes / 1024 - tbytes = tbytes / 1024 - unit = "K" - end - if( fbytes > 1024 && tbytes > 1024 ) - fbytes = fbytes / 1024 - tbytes = tbytes / 1024 - unit = "M" - end - print("#{d} : #{types[t]} (#{fbytes} #{unit}/#{tbytes} #{unit})\n") -} diff --git a/ext/dl/sample/getch.rb b/ext/dl/sample/getch.rb deleted file mode 100644 index 3f7261c979..0000000000 --- a/ext/dl/sample/getch.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'dl' - -crtdll = DL::dlopen("crtdll") -getch = crtdll['_getch', 'L'] -print(getch.call, "\n") diff --git a/ext/dl/sample/libc.rb b/ext/dl/sample/libc.rb deleted file mode 100644 index a1f6fbe543..0000000000 --- a/ext/dl/sample/libc.rb +++ /dev/null @@ -1,69 +0,0 @@ -require "dl/import" -require "dl/struct" - -module LIBC - extend DL::Importable - - begin - dlload "libc.so.6" - rescue - dlload "libc.so.5" - end - - extern "int atoi(char*)" - extern "ibool isdigit(int)" - extern "int gettimeofday(struct timeval *, struct timezone *)" - extern "char* strcat(char*, char*)" - extern "FILE* fopen(char*, char*)" - extern "int fclose(FILE*)" - extern "int fgetc(FILE*)" - extern "int strlen(char*)" - extern "void qsort(void*, int, int, void*)" - - def str_qsort(ary, comp) - len = ary.length - r,rs = qsort(ary, len, DL.sizeof('P'), comp) - return rs[0].to_a('S', len) - end - - Timeval = struct [ - "long tv_sec", - "long tv_usec", - ] - - Timezone = struct [ - "int tz_minuteswest", - "int tz_dsttime", - ] - - def my_compare(ptr1, ptr2) - ptr1.ptr.to_s <=> ptr2.ptr.to_s - end - COMPARE = callback("int my_compare(char**, char**)") -end - - -$cb1 = DL.callback('IPP'){|ptr1, ptr2| - str1 = ptr1.ptr.to_s - str2 = ptr2.ptr.to_s - str1 <=> str2 -} - -p LIBC.atoi("10") - -p LIBC.isdigit(?1) - -p LIBC.isdigit(?a) - -p LIBC.strcat("a", "b") - -ary = ["a","c","b"] -ptr = ary.to_ptr -LIBC.qsort(ptr, ary.length, DL.sizeof('P'), LIBC::COMPARE) -p ptr.to_a('S', ary.length) - -tv = LIBC::Timeval.malloc -tz = LIBC::Timezone.malloc -LIBC.gettimeofday(tv, tz) - -p Time.at(tv.tv_sec) diff --git a/ext/dl/sample/msgbox.rb b/ext/dl/sample/msgbox.rb deleted file mode 100644 index 091e646091..0000000000 --- a/ext/dl/sample/msgbox.rb +++ /dev/null @@ -1,19 +0,0 @@ -# This script works on Windows. - -require 'dl' - -User32 = DL.dlopen("user32") -Kernel32 = DL.dlopen("kernel32") - -MB_OK = 0 -MB_OKCANCEL = 1 - -message_box = User32['MessageBoxA', 'ILSSI'] -r,rs = message_box.call(0, 'ok?', 'error', MB_OKCANCEL) - -case r -when 1 - print("OK!\n") -when 2 - print("Cancel!\n") -end diff --git a/ext/dl/sample/msgbox2.rb b/ext/dl/sample/msgbox2.rb deleted file mode 100644 index e49846cc5e..0000000000 --- a/ext/dl/sample/msgbox2.rb +++ /dev/null @@ -1,18 +0,0 @@ -# This script works on Windows. - -require 'dl/win32' - -MB_OK = 0 -MB_OKCANCEL = 1 - -message_box = Win32API.new("user32",'MessageBoxA', 'ISSI', 'I') -r = message_box.call(0, 'ok?', 'error', MB_OKCANCEL) - -case r -when 1 - print("OK!\n") -when 2 - print("Cancel!\n") -else - p r -end diff --git a/ext/dl/sample/stream.rb b/ext/dl/sample/stream.rb deleted file mode 100644 index 179836999d..0000000000 --- a/ext/dl/sample/stream.rb +++ /dev/null @@ -1,87 +0,0 @@ -# -*- ruby -*- -# Display a file name and stream names of a file with those size. - -require 'dl' -require 'dl/import' - -module NTFS - extend DL::Importable - - dlload "kernel32.dll" - - OPEN_EXISTING = 3 - GENERIC_READ = 0x80000000 - BACKUP_DATA = 0x00000001 - BACKUP_ALTERNATE_DATA = 0x00000004 - FILE_SHARE_READ = 0x00000001 - FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 - - typealias "LPSECURITY_ATTRIBUTES", "void*" - - extern "BOOL BackupRead(HANDLE, PBYTE, DWORD, PDWORD, BOOL, BOOL, PVOID)" - extern "BOOL BackupSeek(HANDLE, DWORD, DWORD, PDWORD, PDWORD, PVOID)" - extern "BOOL CloseHandle(HANDLE)" - extern "HANDLE CreateFile(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, - DWORD, DWORD, HANDLE)" - - module_function - - def streams(filename) - status = [] - h = createFile(filename,GENERIC_READ,FILE_SHARE_READ,nil, - OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0) - if( h != 0 ) - begin - # allocate the memory for backup data used in backupRead(). - data = DL.malloc(DL.sizeof("L5")) - data.struct!("LLLLL", :id, :attrs, :size_low, :size_high, :name_size) - - # allocate memories for references to long values used in backupRead(). - context = DL.malloc(DL.sizeof("L")) - lval = DL.malloc(DL.sizeof("L")) - - while( backupRead(h, data, data.size, lval, false, false, context) ) - size = data[:size_low] + (data[:size_high] << (DL.sizeof("I") * 8)) - case data[:id] - when BACKUP_ALTERNATE_DATA - stream_name = DL.malloc(data[:name_size]) - backupRead(h, stream_name, stream_name.size, - lval, false, false, context) - name = stream_name[0, stream_name.size] - name.tr!("\000","") - if( name =~ /^:(.*?):.*$/ ) - status.push([$1,size]) - end - when BACKUP_DATA - status.push([nil,size]) - else - raise(RuntimeError, "unknown data type #{data[:id]}.") - end - l1 = DL.malloc(DL.sizeof("L")) - l2 = DL.malloc(DL.sizeof("L")) - if( !backupSeek(h, data[:size_low], data[:size_high], l1, l2, context) ) - break - end - end - ensure - backupRead(h, nil, 0, lval, true, false, context) - closeHandle(h) - end - return status - else - raise(RuntimeError, "can't open #{filename}.\n") - end - end -end - -ARGV.each{|filename| - if( File.exist?(filename) ) - NTFS.streams(filename).each{|name,size| - if( name ) - print("#{filename}:#{name}\t#{size}bytes\n") - else - print("#{filename}\t#{size}bytes\n") - end - } - end -} diff --git a/ext/dl/sym.c b/ext/dl/sym.c deleted file mode 100644 index 7151d3c04e..0000000000 --- a/ext/dl/sym.c +++ /dev/null @@ -1,991 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- - * $Id$ - */ - -#include -#include -#include "dl.h" - -VALUE rb_cDLSymbol; - -static const char * -char2type(int ch) -{ - switch (ch) { - case '0': - return "void"; - case 'P': - return "void *"; - case 'p': - return "void *"; - case 'C': - return "char"; - case 'c': - return "char *"; - case 'H': - return "short"; - case 'h': - return "short *"; - case 'I': - return "int"; - case 'i': - return "int *"; - case 'L': - return "long"; - case 'l': - return "long *"; - case 'F': - return "double"; - case 'f': - return "double *"; - case 'D': - return "double"; - case 'd': - return "double *"; - case 'S': - return "const char *"; - case 's': - return "char *"; - case 'A': - return "[]"; - case 'a': - return "[]"; /* ?? */ - } - return NULL; -} - -void -dlsym_free(struct sym_data *data) -{ - if( data->name ){ - DEBUG_CODE({ - printf("dlsym_free(): free(data->name:%s)\n",data->name); - }); - free(data->name); - } - if( data->type ){ - DEBUG_CODE({ - printf("dlsym_free(): free(data->type:%s)\n",data->type); - }); - free(data->type); - } -} - -VALUE -rb_dlsym_new(void (*func)(), const char *name, const char *type) -{ - VALUE val; - struct sym_data *data; - const char *ptype; - - rb_secure(4); - if( !type || !type[0] ){ - return rb_dlptr_new((void*)func, 0, 0); - } - - for( ptype = type; *ptype; ptype ++ ){ - if( ! char2type(*ptype) ){ - rb_raise(rb_eDLTypeError, "unknown type specifier '%c'", *ptype); - } - } - - if( func ){ - val = Data_Make_Struct(rb_cDLSymbol, struct sym_data, 0, dlsym_free, data); - data->func = func; - data->name = name ? strdup(name) : NULL; - data->type = type ? strdup(type) : NULL; - data->len = type ? strlen(type) : 0; -#if !(defined(DLSTACK)) - if( data->len - 1 > MAX_ARG ){ - rb_raise(rb_eDLError, "maximum number of arguments is %d.", MAX_ARG); - } -#endif - } - else{ - val = Qnil; - } - - return val; -} - -freefunc_t -rb_dlsym2csym(VALUE val) -{ - struct sym_data *data; - freefunc_t func; - - if( rb_obj_is_kind_of(val, rb_cDLSymbol) ){ - Data_Get_Struct(val, struct sym_data, data); - func = data->func; - } - else if( val == Qnil ){ - func = NULL; - } - else{ - rb_raise(rb_eTypeError, "DL::Symbol was expected"); - } - - return func; -} - -VALUE -rb_dlsym_s_allocate(VALUE klass) -{ - VALUE obj; - struct sym_data *data; - - obj = Data_Make_Struct(klass, struct sym_data, 0, dlsym_free, data); - data->func = 0; - data->name = 0; - data->type = 0; - data->len = 0; - - return obj; -} - -VALUE -rb_dlsym_initialize(int argc, VALUE argv[], VALUE self) -{ - VALUE addr, name, type; - struct sym_data *data; - void *saddr; - const char *sname, *stype; - - rb_scan_args(argc, argv, "12", &addr, &name, &type); - - saddr = (void*)(DLNUM2LONG(rb_Integer(addr))); - if (!NIL_P(name)) StringValue(name); - stype = NIL_P(type) ? NULL : StringValuePtr(type); - sname = NIL_P(name) ? NULL : RSTRING(name)->ptr; - - if( saddr ){ - Data_Get_Struct(self, struct sym_data, data); - if( data->name ) free(data->name); - if( data->type ) free(data->type); - data->func = saddr; - data->name = sname ? strdup(sname) : 0; - data->type = stype ? strdup(stype) : 0; - data->len = stype ? strlen(stype) : 0; - } - - return Qnil; -} - -VALUE -rb_s_dlsym_char2type(VALUE self, VALUE ch) -{ - const char *type; - - type = char2type(StringValuePtr(ch)[0]); - - if (type == NULL) - return Qnil; - else - return rb_str_new2(type); -} - -VALUE -rb_dlsym_name(VALUE self) -{ - struct sym_data *sym; - - Data_Get_Struct(self, struct sym_data, sym); - return sym->name ? rb_tainted_str_new2(sym->name) : Qnil; -} - -VALUE -rb_dlsym_proto(VALUE self) -{ - struct sym_data *sym; - - Data_Get_Struct(self, struct sym_data, sym); - return sym->type ? rb_tainted_str_new2(sym->type) : Qnil; -} - -VALUE -rb_dlsym_cproto(VALUE self) -{ - struct sym_data *sym; - const char *ptype, *typestr; - size_t len; - VALUE val; - - Data_Get_Struct(self, struct sym_data, sym); - - ptype = sym->type; - - if( ptype ){ - typestr = char2type(*ptype++); - len = strlen(typestr); - - val = rb_tainted_str_new(typestr, len); - if (typestr[len - 1] != '*') - rb_str_cat(val, " ", 1); - - if( sym->name ){ - rb_str_cat2(val, sym->name); - } - else{ - rb_str_cat2(val, "(null)"); - } - rb_str_cat(val, "(", 1); - - while (*ptype) { - const char *ty = char2type(*ptype++); - rb_str_cat2(val, ty); - if (*ptype) - rb_str_cat(val, ", ", 2); - } - - rb_str_cat(val, ");", 2); - } - else{ - val = rb_tainted_str_new2("void ("); - if( sym->name ){ - rb_str_cat2(val, sym->name); - } - else{ - rb_str_cat2(val, "(null)"); - } - rb_str_cat2(val, ")()"); - } - - return val; -} - -VALUE -rb_dlsym_inspect(VALUE self) -{ - VALUE proto; - VALUE val; - char *str; - int str_size; - struct sym_data *sym; - - Data_Get_Struct(self, struct sym_data, sym); - proto = rb_dlsym_cproto(self); - - str_size = RSTRING(proto)->len + 100; - str = dlmalloc(str_size); - snprintf(str, str_size - 1, - "#", - sym, sym->func, RSTRING(proto)->ptr); - val = rb_tainted_str_new2(str); - dlfree(str); - - return val; -} - -static int -stack_size(struct sym_data *sym) -{ - int i; - int size; - - size = 0; - for( i=1; i < sym->len; i++ ){ - switch(sym->type[i]){ - case 'C': - case 'H': - case 'I': - case 'L': - size += sizeof(long); - break; - case 'F': - size += sizeof(float); - break; - case 'D': - size += sizeof(double); - break; - case 'c': - case 'h': - case 'i': - case 'l': - case 'f': - case 'd': - case 'p': - case 'P': - case 's': - case 'S': - case 'a': - case 'A': - size += sizeof(void*); - break; - default: - return -(sym->type[i]); - } - } - return size; -} - -static ID rb_dl_id_DLErrno; - -static VALUE -rb_dl_get_last_error(VALUE self) -{ - return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLErrno); -} - -static VALUE -rb_dl_set_last_error(VALUE self, VALUE val) -{ - errno = NUM2INT(val); - rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, val); - return Qnil; -} - -#ifdef HAVE_WINDOWS_H -#include -static ID rb_dl_id_DLW32Error; - -static VALUE -rb_dl_win32_get_last_error(VALUE self) -{ - return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLW32Error); -} - -static VALUE -rb_dl_win32_set_last_error(VALUE self, VALUE val) -{ - SetLastError(NUM2INT(val)); - rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, val); - return Qnil; -} -#endif - -#ifdef DLSTACK_GUARD -# ifdef __MSVC_RUNTIME_CHECKS -# pragma runtime_checks("s", off) -# endif -# if _MSC_VER >= 1300 -__declspec(noinline) -# endif -static int -rb_dlsym_guardcall(char type, ANY_TYPE *ret, long *stack, void *func) -{ - char *volatile guard = ALLOCA_N(char, 1); /* guard stack pointer */ - switch(type){ - case '0': - { - void (*f)(DLSTACK_PROTO) = func; - f(DLSTACK_ARGS); - } - break; - case 'P': - case 'p': - { - void * (*f)(DLSTACK_PROTO) = func; - ret->p = f(DLSTACK_ARGS); - } - break; - case 'C': - case 'c': - { - char (*f)(DLSTACK_PROTO) = func; - ret->c = f(DLSTACK_ARGS); - } - break; - case 'H': - case 'h': - { - short (*f)(DLSTACK_PROTO) = func; - ret->h = f(DLSTACK_ARGS); - } - break; - case 'I': - case 'i': - { - int (*f)(DLSTACK_PROTO) = func; - ret->i = f(DLSTACK_ARGS); - } - break; - case 'L': - case 'l': - { - long (*f)(DLSTACK_PROTO) = func; - ret->l = f(DLSTACK_ARGS); - } - break; - case 'F': - case 'f': - { - float (*f)(DLSTACK_PROTO) = func; - ret->f = f(DLSTACK_ARGS); - } - break; - case 'D': - case 'd': - { - double (*f)(DLSTACK_PROTO) = func; - ret->d = f(DLSTACK_ARGS); - } - break; - case 'S': - case 's': - { - char * (*f)(DLSTACK_PROTO) = func; - ret->s = f(DLSTACK_ARGS); - } - break; - default: - return 0; - } - return 1; -} -# ifdef __MSVC_RUNTIME_CHECKS -# pragma runtime_checks("s", restore) -# endif -#endif /* defined(DLSTACK_GUARD) */ - -VALUE -rb_dlsym_call(int argc, VALUE argv[], VALUE self) -{ - struct sym_data *sym; - ANY_TYPE *args; - ANY_TYPE *dargs; - ANY_TYPE ret; - int *dtypes; - VALUE val; - VALUE dvals; - int i; - long ftype; - void *func; - - rb_secure_update(self); - Data_Get_Struct(self, struct sym_data, sym); - DEBUG_CODE({ - printf("rb_dlsym_call(): type = '%s', func = 0x%x\n", sym->type, sym->func); - }); - if( (sym->len - 1) != argc ){ - rb_raise(rb_eArgError, "%d arguments are needed", sym->len - 1); - } - - ftype = 0; - dvals = Qnil; - - args = ALLOC_N(ANY_TYPE, sym->len - 1); - dargs = ALLOC_N(ANY_TYPE, sym->len - 1); - dtypes = ALLOC_N(int, sym->len - 1); -#define FREE_ARGS {xfree(args); xfree(dargs); xfree(dtypes);} - - for( i = sym->len - 2; i >= 0; i-- ){ - dtypes[i] = 0; - - switch( sym->type[i+1] ){ - case 'p': - dtypes[i] = 'p'; - case 'P': - { - struct ptr_data *data; - VALUE pval; - - if( argv[i] == Qnil ){ - ANY2P(args[i]) = DLVOIDP(0); - } - else{ - if( rb_obj_is_kind_of(argv[i], rb_cDLPtrData) ){ - pval = argv[i]; - } - else{ - pval = rb_funcall(argv[i], rb_intern("to_ptr"), 0); - if( !rb_obj_is_kind_of(pval, rb_cDLPtrData) ){ - rb_raise(rb_eDLTypeError, "unexpected type of argument #%d", i); - } - } - Data_Get_Struct(pval, struct ptr_data, data); - ANY2P(args[i]) = DLVOIDP(data->ptr); - } - } - PUSH_P(ftype); - break; - case 'a': - dtypes[i] = 'a'; - case 'A': - if( argv[i] == Qnil ){ - ANY2P(args[i]) = DLVOIDP(0); - } - else{ - ANY2P(args[i]) = DLVOIDP(rb_ary2cary(0, argv[i], NULL)); - } - PUSH_P(ftype); - break; - case 'C': - ANY2C(args[i]) = DLCHAR(NUM2CHR(argv[i])); - PUSH_C(ftype); - break; - case 'c': - ANY2C(dargs[i]) = DLCHAR(NUM2CHR(argv[i])); - ANY2P(args[i]) = DLVOIDP(&(ANY2C(dargs[i]))); - dtypes[i] = 'c'; - PUSH_P(ftype); - break; - case 'H': - ANY2H(args[i]) = DLSHORT(NUM2INT(argv[i])); - PUSH_C(ftype); - break; - case 'h': - ANY2H(dargs[i]) = DLSHORT(NUM2INT(argv[i])); - ANY2P(args[i]) = DLVOIDP(&(ANY2H(dargs[i]))); - dtypes[i] = 'h'; - PUSH_P(ftype); - break; - case 'I': - ANY2I(args[i]) = DLINT(NUM2INT(argv[i])); - PUSH_I(ftype); - break; - case 'i': - ANY2I(dargs[i]) = DLINT(NUM2INT(argv[i])); - ANY2P(args[i]) = DLVOIDP(&(ANY2I(dargs[i]))); - dtypes[i] = 'i'; - PUSH_P(ftype); - break; - case 'L': - ANY2L(args[i]) = DLNUM2LONG(argv[i]); - PUSH_L(ftype); - break; - case 'l': - ANY2L(dargs[i]) = DLNUM2LONG(argv[i]); - ANY2P(args[i]) = DLVOIDP(&(ANY2L(dargs[i]))); - dtypes[i] = 'l'; - PUSH_P(ftype); - break; - case 'F': - Check_Type(argv[i], T_FLOAT); - ANY2F(args[i]) = DLFLOAT(RFLOAT(argv[i])->value); - PUSH_F(ftype); - break; - case 'f': - Check_Type(argv[i], T_FLOAT); - ANY2F(dargs[i]) = DLFLOAT(RFLOAT(argv[i])->value); - ANY2P(args[i]) = DLVOIDP(&(ANY2F(dargs[i]))); - dtypes[i] = 'f'; - PUSH_P(ftype); - break; - case 'D': - Check_Type(argv[i], T_FLOAT); - ANY2D(args[i]) = RFLOAT(argv[i])->value; - PUSH_D(ftype); - break; - case 'd': - Check_Type(argv[i], T_FLOAT); - ANY2D(dargs[i]) = RFLOAT(argv[i])->value; - ANY2P(args[i]) = DLVOIDP(&(ANY2D(dargs[i]))); - dtypes[i] = 'd'; - PUSH_P(ftype); - break; - case 'S': - if( argv[i] == Qnil ){ - ANY2S(args[i]) = DLSTR(0); - } - else{ - VALUE str = argv[i]; - SafeStringValue(str); - ANY2S(args[i]) = DLSTR(RSTRING(str)->ptr); - } - PUSH_P(ftype); - break; - case 's': - { - VALUE str = argv[i]; - SafeStringValue(str); - ANY2S(args[i]) = DLSTR(dlmalloc(RSTRING(str)->len + 1)); - memcpy((char*)(ANY2S(args[i])), RSTRING(str)->ptr, RSTRING(str)->len + 1); - dtypes[i] = 's'; - } - PUSH_P(ftype); - break; - default: - FREE_ARGS; - rb_raise(rb_eDLTypeError, - "unknown type '%c' of the return value.", - sym->type[i+1]); - } - } - - switch( sym->type[0] ){ - case '0': - PUSH_0(ftype); - break; - case 'P': - case 'p': - case 'S': - case 's': - case 'A': - case 'a': - PUSH_P(ftype); - break; - case 'C': - case 'c': - PUSH_C(ftype); - break; - case 'H': - case 'h': - PUSH_H(ftype); - break; - case 'I': - case 'i': - PUSH_I(ftype); - break; - case 'L': - case 'l': - PUSH_L(ftype); - break; - case 'F': - case 'f': - PUSH_F(ftype); - break; - case 'D': - case 'd': - PUSH_D(ftype); - break; - default: - FREE_ARGS; - rb_raise(rb_eDLTypeError, - "unknown type `%c' of the return value.", - sym->type[0]); - } - - func = sym->func; - -#if defined(DLSTACK) - { -#if defined(DLSTACK_SIZE) - int stk_size; - long stack[DLSTACK_SIZE]; - long *sp; - - sp = stack; - stk_size = stack_size(sym); - if( stk_size < 0 ){ - FREE_ARGS; - rb_raise(rb_eDLTypeError, "unknown type '%c'.", -stk_size); - } - else if( stk_size > (int)(DLSTACK_SIZE) ){ - FREE_ARGS; - rb_raise(rb_eArgError, "too many arguments."); - } -#endif - - DLSTACK_START(sym); - -#if defined(DLSTACK_REVERSE) - for( i = sym->len - 2; i >= 0; i-- ) -#else - for( i = 0; i <= sym->len -2; i++ ) -#endif - { - switch( sym->type[i+1] ){ - case 'p': - case 'P': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'a': - case 'A': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'C': - DLSTACK_PUSH_C(ANY2C(args[i])); - break; - case 'c': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'H': - DLSTACK_PUSH_H(ANY2H(args[i])); - break; - case 'h': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'I': - DLSTACK_PUSH_I(ANY2I(args[i])); - break; - case 'i': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'L': - DLSTACK_PUSH_L(ANY2L(args[i])); - break; - case 'l': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'F': - DLSTACK_PUSH_F(ANY2F(args[i])); - break; - case 'f': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'D': - DLSTACK_PUSH_D(ANY2D(args[i])); - break; - case 'd': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; - case 'S': - case 's': - DLSTACK_PUSH_P(ANY2S(args[i])); - break; - } - } - DLSTACK_END(sym->type); - -#ifdef DLSTACK_GUARD - if(!rb_dlsym_guardcall(sym->type[0], &ret, stack, func)) { - FREE_ARGS; - rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); - } -#else /* defined(DLSTACK_GUARD) */ - { - switch( sym->type[0] ){ - case '0': - { - void (*f)(DLSTACK_PROTO) = func; - f(DLSTACK_ARGS); - } - break; - case 'P': - case 'p': - { - void * (*f)(DLSTACK_PROTO) = func; - ret.p = f(DLSTACK_ARGS); - } - break; - case 'C': - case 'c': - { - char (*f)(DLSTACK_PROTO) = func; - ret.c = f(DLSTACK_ARGS); - } - break; - case 'H': - case 'h': - { - short (*f)(DLSTACK_PROTO) = func; - ret.h = f(DLSTACK_ARGS); - } - break; - case 'I': - case 'i': - { - int (*f)(DLSTACK_PROTO) = func; - ret.i = f(DLSTACK_ARGS); - } - break; - case 'L': - case 'l': - { - long (*f)(DLSTACK_PROTO) = func; - ret.l = f(DLSTACK_ARGS); - } - break; - case 'F': - case 'f': - { - float (*f)(DLSTACK_PROTO) = func; - ret.f = f(DLSTACK_ARGS); - } - break; - case 'D': - case 'd': - { - double (*f)(DLSTACK_PROTO) = func; - ret.d = f(DLSTACK_ARGS); - } - break; - case 'S': - case 's': - { - char * (*f)(DLSTACK_PROTO) = func; - ret.s = f(DLSTACK_ARGS); - } - break; - default: - FREE_ARGS; - rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); - } - } -#endif /* defubed(DLSTACK_GUARD) */ - - { - /* - * We should get the value of errno/GetLastError() before calling another functions. - */ - int last_errno = errno; -#ifdef _WIN32 - DWORD win32_last_err = GetLastError(); -#endif - - rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, INT2NUM(last_errno)); -#ifdef _WIN32 - rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, INT2NUM(win32_last_err)); -#endif - } - - } -#else /* defined(DLSTACK) */ - switch(ftype){ -#include "call.func" - default: - FREE_ARGS; - rb_raise(rb_eDLTypeError, "unsupported function type `%s'", sym->type); - } -#endif /* defined(DLSTACK) */ - - switch( sym->type[0] ){ - case '0': - val = Qnil; - break; - case 'P': - val = rb_dlptr_new((void*)(ANY2P(ret)), 0, 0); - break; - case 'p': - val = rb_dlptr_new((void*)(ANY2P(ret)), 0, dlfree); - break; - case 'C': - case 'c': - val = CHR2FIX((char)(ANY2C(ret))); - break; - case 'H': - case 'h': - val = INT2NUM((short)(ANY2H(ret))); - break; - case 'I': - case 'i': - val = INT2NUM((int)(ANY2I(ret))); - break; - case 'L': - case 'l': - val = DLLONG2NUM((long)(ANY2L(ret))); - break; - case 'F': - case 'f': - val = rb_float_new((double)(ANY2F(ret))); - break; - case 'D': - case 'd': - val = rb_float_new((double)(ANY2D(ret))); - break; - case 'S': - if( ANY2S(ret) ){ - val = rb_tainted_str_new2((char*)(ANY2S(ret))); - } - else{ - val = Qnil; - } - break; - case 's': - if( ANY2S(ret) ){ - val = rb_tainted_str_new2((char*)(ANY2S(ret))); - DEBUG_CODE({ - printf("dlfree(%s)\n",(char*)(ANY2S(ret))); - }); - dlfree((void*)(ANY2S(ret))); - } - else{ - val = Qnil; - } - break; - default: - FREE_ARGS; - rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); - } - - dvals = rb_ary_new(); - for( i = 0; i <= sym->len - 2; i++ ){ - if( dtypes[i] ){ - switch( dtypes[i] ){ - case 'c': - rb_ary_push(dvals, CHR2FIX(*((char*)(ANY2P(args[i]))))); - break; - case 'h': - rb_ary_push(dvals, INT2NUM(*((short*)(ANY2P(args[i]))))); - break; - case 'i': - rb_ary_push(dvals, INT2NUM(*((int*)(ANY2P(args[i]))))); - break; - case 'l': - rb_ary_push(dvals, DLLONG2NUM(*((long*)(ANY2P(args[i]))))); - break; - case 'f': - rb_ary_push(dvals, rb_float_new(*((float*)(ANY2P(args[i]))))); - break; - case 'd': - rb_ary_push(dvals, rb_float_new(*((double*)(ANY2P(args[i]))))); - break; - case 'p': - rb_ary_push(dvals, rb_dlptr_new((void*)(ANY2P(args[i])), 0, 0)); - break; - case 'a': - rb_ary_push(dvals, rb_dlptr_new((void*)ANY2P(args[i]), 0, 0)); - break; - case 's': - rb_ary_push(dvals, rb_tainted_str_new2((char*)ANY2S(args[i]))); - DEBUG_CODE({ - printf("dlfree(%s)\n",(char*)ANY2S(args[i])); - }); - dlfree((void*)ANY2S(args[i])); - break; - default: - { - char c = dtypes[i]; - FREE_ARGS; - rb_raise(rb_eRuntimeError, "unknown argument type '%c'", i, c); - } - } - } - else{ - switch( sym->type[i+1] ){ - case 'A': - dlfree((void*)ANY2P(args[i])); - break; - } - rb_ary_push(dvals, argv[i]); - } - } - -#undef FREE_ARGS - return rb_assoc_new(val,dvals); -} - -VALUE -rb_dlsym_to_i(VALUE self) -{ - struct sym_data *sym; - - Data_Get_Struct(self, struct sym_data, sym); - return DLLONG2NUM(sym); -} - -VALUE -rb_dlsym_to_ptr(VALUE self) -{ - struct sym_data *sym; - - Data_Get_Struct(self, struct sym_data, sym); - return rb_dlptr_new(sym->func, sizeof(freefunc_t), 0); -} - -void -Init_dlsym() -{ - rb_cDLSymbol = rb_define_class_under(rb_mDL, "Symbol", rb_cObject); - rb_define_alloc_func(rb_cDLSymbol, rb_dlsym_s_allocate); - rb_define_singleton_method(rb_cDLSymbol, "char2type", rb_s_dlsym_char2type, 1); - rb_define_method(rb_cDLSymbol, "initialize", rb_dlsym_initialize, -1); - rb_define_method(rb_cDLSymbol, "call", rb_dlsym_call, -1); - rb_define_method(rb_cDLSymbol, "[]", rb_dlsym_call, -1); - rb_define_method(rb_cDLSymbol, "name", rb_dlsym_name, 0); - rb_define_method(rb_cDLSymbol, "proto", rb_dlsym_proto, 0); - rb_define_method(rb_cDLSymbol, "cproto", rb_dlsym_cproto, 0); - rb_define_method(rb_cDLSymbol, "inspect", rb_dlsym_inspect, 0); - rb_define_method(rb_cDLSymbol, "to_s", rb_dlsym_cproto, 0); - rb_define_method(rb_cDLSymbol, "to_ptr", rb_dlsym_to_ptr, 0); - rb_define_method(rb_cDLSymbol, "to_i", rb_dlsym_to_i, 0); - - rb_dl_id_DLErrno = rb_intern("DLErrno"); - rb_define_singleton_method(rb_mDL, "last_error", rb_dl_get_last_error, 0); - rb_define_singleton_method(rb_mDL, "last_error=", rb_dl_set_last_error, 1); -#ifdef _WIN32 - rb_dl_id_DLW32Error = rb_intern("DLW32Error"); - rb_define_singleton_method(rb_mDL, "win32_last_error", rb_dl_win32_get_last_error, 0); - rb_define_singleton_method(rb_mDL, "win32_last_error=", rb_dl_win32_set_last_error, 1); -#endif -} diff --git a/ext/dl/test/libtest.def b/ext/dl/test/libtest.def deleted file mode 100644 index 8ecefc917b..0000000000 --- a/ext/dl/test/libtest.def +++ /dev/null @@ -1,28 +0,0 @@ -EXPORTS -test_alloc_test_struct -test_append -test_arylen -test_c2i -test_call_func1 -test_callback1 -test_close -test_d2f -test_f2d -test_fill_test_struct -test_fill_test_union -test_gets -test_i2c -test_init -test_isucc -test_lcc -test_lsucc -test_open -test_strcat -test_strlen -test_succ -test_data_init -test_data_add -test_data_aref -test_set_long_value -test_get_long_value -internal_long_value diff --git a/ext/dl/test/test.c b/ext/dl/test/test.c deleted file mode 100644 index 7321379390..0000000000 --- a/ext/dl/test/test.c +++ /dev/null @@ -1,247 +0,0 @@ -#include -#include - -static char internal_string[] = "internal_string"; -long internal_long_value = 100; - -struct test_struct { - char c; - long l; -}; - -union test_union { - char c; - int i; - long l; - void *p; -}; - -struct test_data { - char name[1024]; - struct test_data *next; -}; - -long -test_get_long_value() -{ - return internal_long_value; -}; - -void -test_set_long_value(long l) -{ - internal_long_value = l; -}; - -void -test_fill_test_struct(struct test_struct *ptr, char c, long l) -{ - ptr->c = c; - ptr->l = l; -}; - -void -test_fill_test_union(union test_union *ptr, long l) -{ - ptr->l = l; -}; - -struct test_struct * -test_alloc_test_struct(char c, long l) -{ - struct test_struct *data; - - data = (struct test_struct *)malloc(sizeof(struct test_struct)); - data->c = c; - data->l = l; - - return data; -}; - -int -test_c2i(char c) -{ - return (int)c; -}; - -char -test_i2c(int i) -{ - return (char)i; -}; - -long -test_lcc(char c1, char c2) -{ - return (long)(c1 + c2); -}; - -double -test_f2d(float f) -{ - double d; - d = f; - return d; -}; - -float -test_d2f(double d) -{ - float f; - f = d; - return f; -}; - -int -test_strlen(const char *str) -{ - return strlen(str); -}; - -int -test_isucc(int i) -{ - return (i+1); -}; - -long -test_lsucc(long l) -{ - return (l+1); -}; - -void -test_succ(long *l) -{ - (*l)++; -}; - -char * -test_strcat(char *str1, const char *str2) -{ - return strcat(str1, str2); -}; - -int -test_arylen(char *ary[]) -{ - int i; - for( i=0; ary[i]; i++ ){}; - return i; -}; - -void -test_append(char *ary[], int len, char *astr) -{ - int i; - int size1,size2; - char *str; - - size2 = strlen(astr); - - for( i=0; i <= len - 1; i++ ){ - size1 = strlen(ary[i]); - str = (char*)malloc(size1 + size2 + 1); - strcpy(str, ary[i]); - strcat(str, astr); - ary[i] = str; - }; -}; - -int -test_init(int *argc, char **argv[]) -{ - int i; - char s[256]; - - for( i=0; i < (*argc); i++ ){ - sprintf(s, "arg%d", i); - if( strcmp((*argv)[i], s) != 0 ){ - return 1; - } - } - return 0; -} - -FILE * -test_open(const char *filename, const char *mode) -{ - FILE *file; - file = fopen(filename,mode); - return file; -}; - -void -test_close(FILE *file) -{ - fclose(file); -}; - -char * -test_gets(char *s, int size, FILE *f) -{ - return fgets(s,size,f); -}; - -typedef int callback1_t(int, char *); -#define CALLBACK_MSG "callback message" - -int -test_callback1(int err, const char *msg) -{ - if( strcmp(msg, CALLBACK_MSG) == 0 ){ - return 1; - } - else{ - return 0; - } -} - -int -test_call_func1(callback1_t *func) -{ - if( func ){ - return (*func)(0, CALLBACK_MSG); - } - else{ - return 0; - } -} - -struct test_data * -test_data_init() -{ - struct test_data *data; - - data = (struct test_data *)malloc(sizeof(struct test_data)); - data->next = NULL; - memset(data->name, 0, 1024); - - return data; -}; - -void -test_data_add(struct test_data *list, const char *name) -{ - struct test_data *data; - - data = (struct test_data *)malloc(sizeof(struct test_data)); - memset(data->name, 0, 1024); - strncpy(data->name, name, 1024); - data->next = list->next; - list->next = data; -}; - -struct test_data * -test_data_aref(struct test_data *list, int i) -{ - struct test_data *data; - int j; - - for( data = list->next, j=0; data; data = data->next, j++ ){ - if( i == j ){ - return data; - }; - }; - return NULL; -}; diff --git a/ext/dl/test/test.rb b/ext/dl/test/test.rb deleted file mode 100644 index 52be04699f..0000000000 --- a/ext/dl/test/test.rb +++ /dev/null @@ -1,295 +0,0 @@ -# -*- ruby -*- - -require 'dl' -require 'dl/import' - -$FAIL = 0 -$TOTAL = 0 - -def assert(label, ty, *conds) - $TOTAL += 1 - cond = !conds.include?(false) - if( cond ) - printf("succeed in `#{label}'\n") - else - $FAIL += 1 - case ty - when :may - printf("fail in `#{label}' ... expected\n") - when :must - printf("fail in `#{label}' ... unexpected\n") - when :raise - raise(RuntimeError, "fail in `#{label}'") - end - end -end - -def debug(*xs) - if( $DEBUG ) - xs.each{|x| - p x - } - end -end - -print("DLSTACK = #{DL::DLSTACK}\n") -print("MAX_ARG = #{DL::MAX_ARG}\n") -print("\n") -print("DL::FREE = #{DL::FREE.inspect}\n") -print("\n") - -$LIB = nil -if( !$LIB && File.exist?("libtest.so") ) - $LIB = "./libtest.so" -end -if( !$LIB && File.exist?("test/libtest.so") ) - $LIB = "./test/libtest.so" -end - -module LIBTest - extend DL::Importable - - dlload($LIB) - extern "int test_c2i(char)" - extern "char test_i2c(int)" - extern "long test_lcc(char, char)" - extern "double test_f2d(float)" - extern "float test_d2f(double)" - extern "int test_strlen(char*)" - extern "int test_isucc(int)" - extern "long test_lsucc(long)" - extern "void test_succ(long *)" - extern "int test_arylen(int [])" - extern "void test_append(char*[], int, char *)" -end - -DL.dlopen($LIB){|h| - c2i = h["test_c2i","IC"] - debug c2i - r,rs = c2i[?a] - debug r,rs - assert("c2i", :may, r == ?a) - assert("extern c2i", :must, r == LIBTest.test_c2i(?a)) - - i2c = h["test_i2c","CI"] - debug i2c - r,rs = i2c[?a] - debug r,rs - assert("i2c", :may, r == ?a) - assert("exern i2c", :must, r == LIBTest.test_i2c(?a)) - - lcc = h["test_lcc","LCC"] - debug lcc - r,rs = lcc[1,2] - assert("lcc", :may, r == 3) - assert("extern lcc", :must, r == LIBTest.test_lcc(1,2)) - - f2d = h["test_f2d","DF"] - debug f2d - r,rs = f2d[20.001] - debug r,rs - assert("f2d", :may, r.to_i == 20) - assert("extern f2d", :must, r = LIBTest.test_f2d(20.001)) - - d2f = h["test_d2f","FD"] - debug d2f - r,rs = d2f[20.001] - debug r,rs - assert("d2f", :may, r.to_i == 20) - assert("extern d2f", :must, r == LIBTest.test_d2f(20.001)) - - strlen = h["test_strlen","IS"] - debug strlen - r,rs = strlen["0123456789"] - debug r,rs - assert("strlen", :must, r == 10) - assert("extern strlen", :must, r == LIBTest.test_strlen("0123456789")) - - isucc = h["test_isucc","II"] - debug isucc - r,rs = isucc[2] - debug r,rs - assert("isucc", :must, r == 3) - assert("extern isucc", :must, r == LIBTest.test_isucc(2)) - - lsucc = h["test_lsucc","LL"] - debug lsucc - r,rs = lsucc[10000000] - debug r,rs - assert("lsucc", :must, r == 10000001) - assert("extern lsucc", :must, r == LIBTest.test_lsucc(10000000)) - - succ = h["test_succ","0l"] - debug succ - r,rs = succ[0] - debug r,rs - assert("succ", :must, rs[0] == 1) - l = DL.malloc(DL.sizeof("L")) - l.struct!("L",:lval) - LIBTest.test_succ(l) - assert("extern succ", :must, rs[0] == l[:lval]) - - arylen = h["test_arylen","IA"] - debug arylen - r,rs = arylen[["a","b","c","d",nil]] - debug r,rs - assert("arylen", :must, r == 4) - - arylen = h["test_arylen","IP"] - debug arylen - r,rs = arylen[["a","b","c","d",nil]] - debug r,rs - assert("arylen", :must, r == 4) - assert("extern arylen", :must, r == LIBTest.test_arylen(["a","b","c","d",nil])) - - append = h["test_append","0aIS"] - debug append - r,rs = append[["a","b","c"],3,"x"] - debug r,rs - assert("append", :must, rs[0].to_a('S',3) == ["ax","bx","cx"]) - - LIBTest.test_append(["a","b","c"],3,"x") - assert("extern append", :must, rs[0].to_a('S',3) == LIBTest._args_[0].to_a('S',3)) - - strcat = h["test_strcat","SsS"] - debug strcat - r,rs = strcat["abc\0","x"] - debug r,rs - assert("strcat", :must, rs[0].to_s == "abcx") - - init = h["test_init","IiP"] - debug init - argc = 3 - argv = ["arg0","arg1","arg2"].to_ptr - r,rs = init[argc, argv.ref] - assert("init", :must, r == 0) -} - - -h = DL.dlopen($LIB) - -sym_open = h["test_open", "PSS"] -sym_gets = h["test_gets", "SsIP"] -sym_close = h["test_close", "0P"] -debug sym_open,sym_gets,sym_close - -line = "Hello world!\n" -File.open("tmp.txt", "w"){|f| - f.print(line) -} - -fp,rs = sym_open["tmp.txt", "r"] -if( fp ) - fp.free = sym_close - r,rs = sym_gets[" " * 256, 256, fp] - debug r,rs - assert("open,gets", :must, rs[0] == line) - ObjectSpace.define_finalizer(fp) {File.unlink("tmp.txt")} - fp = nil -else - assert("open,gets", :must, line == nil) - File.unlink("tmp.txt") -end - - -callback1 = h["test_callback1"] -debug callback1 -r,rs = h["test_call_func1", "IP"][callback1] -debug r,rs -assert("callback1", :must, r == 1) - - -callback2 = DL.callback("LLP"){|num,ptr| - msg = ptr.to_s - if( msg == "callback message" ) - 2 - else - 0 - end -} -debug callback2 -r,rs = h["test_call_func1", "IP"][callback2] -debug r,rs -assert("callback2", :must, r == 2) -DL.remove_callback(callback2) - -ptr = DL.malloc(DL.sizeof('CL')) -ptr.struct!("CL", :c, :l) -ptr["c"] = 0 -ptr["l"] = 0 -r,rs = h["test_fill_test_struct","0PIL"][ptr,100,1000] -debug r,rs -assert("fill_test_struct", :must, ptr["c"] == 100, ptr["l"] == 1000) -assert("fill_test_struct", :must, ptr[:c] == 100, ptr[:l] == 1000) unless (Fixnum === :-) - - -r,rs = h["test_alloc_test_struct", "PIL"][100,200] -r.free = DL::FREE -r.struct!("CL", :c, :l) -assert("alloc_test_struct", :must, r["c"] == 100, r["l"] == 200) -assert("alloc_test_struct", :must, r[:c] == 100, r[:l] == 200) unless (Fixnum === :-) - -ptr = h["test_strlen"] -sym1 = DL::Symbol.new(ptr,"foo","0") -sym2 = h["test_strlen","LS"] -assert("Symbol.new", :must, ptr == sym1.to_ptr, sym1.to_ptr == sym2.to_ptr) - -set_val = h["test_set_long_value","0"] -get_val = h["test_get_long_value","L"] -lval = get_val[][0] -ptr = h["internal_long_value"] -ptr.struct!("L", :l) -assert("get value", :must, ptr["l"] == lval) -assert("get value", :must, ptr[:l] == lval) unless (Fixnum === :-) -ptr["l"] = 200 -lval = get_val[][0] -assert("set value", :must, ptr["l"] == lval) -assert("set value", :must, ptr[:l] == lval) unless (Fixnum === :-) - - -data_init = h["test_data_init", "P"] -data_add = h["test_data_add", "0PS"] -data_aref = h["test_data_aref", "PPI"] -r,rs = data_init[] -ptr = r -data_add[ptr, "name1"] -data_add[ptr, "name2"] -data_add[ptr, "name3"] - -r,rs = data_aref[ptr, 1] -ptr = r -ptr.struct!("C1024P", :name, :next) -assert("data_aref", :must, - ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name2") -assert("data_aref", :must, - ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name2") unless (Fixnum === :-) - -ptr = ptr["next"] -ptr.struct!("C1024P", :name, :next) -assert("data_aref", :must, - ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name1") -assert("data_aref", :must, - ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name1") unless (Fixnum === :-) - -GC.start - -ptr = DL::malloc(1024) -ptr.struct!("CHIL", "c", "h", "i", "l") -ptr["c"] = 1 -ptr["h"] = 2 -ptr["i"] = 3 -ptr["l"] = 4 -assert("struct!", :must, - ptr["c"] == 1 && - ptr["h"] == 2 && - ptr["i"] == 3 && - ptr["l"] == 4) - -ptr = DL::malloc(DL::sizeof("IP")) -ptr.struct!("IP", "n", "ptr") -ptr["n"] = 10 -ptr["ptr"] = nil -assert("struct!", :must, ptr["n"] == 10 && ptr["ptr"] == nil) - -GC.start -printf("fail/total = #{$FAIL}/#{$TOTAL}\n") diff --git a/ext/dl/type.rb b/ext/dl/type.rb deleted file mode 100644 index 804420c395..0000000000 --- a/ext/dl/type.rb +++ /dev/null @@ -1,115 +0,0 @@ -# example: -# DLTYPE[INT][:rb2c]["arg0"] => "NUM2INT(arg0)" -# DLTYPE[DOUBLE][:c2rb]["r"] => "rb_float_new(r)" - -DLTYPE = { - VOID = 0x00 => { - :name => 'VOID', - :rb2c => nil, - :c2rb => nil, - :ctype => "void", - :stmem => "v", - :sym => true, - :cb => true, - }, - CHAR = 0x01 => { - :name => 'CHAR', - :rb2c => proc{|x| "NUM2CHR(#{x})"}, - :c2rb => proc{|x| "CHR2FIX(#{x})"}, - :ctype => "char", - :stmem => "c", - :sym => false, - :cb => false, - }, - SHORT = 0x02 => { - :name => 'SHORT', - :rb2c => proc{|x| "FIX2INT(#{x})"}, - :c2rb => proc{|x| "INT2FIX(#{x})"}, - :ctype => "short", - :stmem => "h", - :sym => false, - :cb => false, - }, - INT = 0x03 => { - :name => 'INT', - :rb2c => proc{|x| "NUM2INT(#{x})"}, - :c2rb => proc{|x| "INT2NUM(#{x})"}, - :ctype => "int", - :stmem => "i", - :sym => true, - :cb => false, - }, - LONG = 0x04 => { - :name => 'LONG', - :rb2c => proc{|x| "NUM2INT(#{x})"}, - :c2rb => proc{|x| "INT2NUM(#{x})"}, - :ctype => "long", - :stmem => "l", - :sym => true, - :cb => true, - }, - FLOAT = 0x05 => { - :name => 'FLOAT', - :rb2c => proc{|x| "(float)(RFLOAT(#{x})->value)"}, - :c2rb => proc{|x| "rb_float_new((double)#{x})"}, - :ctype => "float", - :stmem => "f", - :sym => false, - :cb => false, - }, - DOUBLE = 0x06 => { - :name => 'DOUBLE', - :rb2c => proc{|x| "RFLOAT(#{x})->value"}, - :c2rb => proc{|x| "rb_float_new(#{x})"}, - :ctype => "double", - :stmem => "d", - :sym => true, - :cb => true, - }, - VOIDP = 0x07 => { - :name => 'VOIDP', - :rb2c => proc{|x| "rb_dlptr2cptr(#{x})"}, - :c2rb => proc{|x| "rb_dlptr_new(#{x},sizeof(void*),0)"}, - :ctype => "void *", - :stmem => "p", - :sym => true, - :cb => true, - }, -} - -def tpush(t, x) - (t << 3)|x -end - -def tget(t, i) - (t & (0x07 << (i * 3))) >> (i * 3) -end - -def types2num(types) - res = 0x00 - r = types.reverse - r.each{|t| - res = tpush(res,t) - } - res -end - -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 - -def types2ctypes(types) - res = [] - types.each{|t| - res.push(DLTYPE[t][:ctype]) - } - res -end