summaryrefslogtreecommitdiff
path: root/trunk/ext/dl
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ext/dl')
-rw-r--r--trunk/ext/dl/.cvsignore10
-rw-r--r--trunk/ext/dl/cfunc.c516
-rw-r--r--trunk/ext/dl/cptr.c482
-rw-r--r--trunk/ext/dl/depend11
-rw-r--r--trunk/ext/dl/dl.c137
-rw-r--r--trunk/ext/dl/dl.h190
-rw-r--r--trunk/ext/dl/extconf.rb31
-rw-r--r--trunk/ext/dl/handle.c227
-rw-r--r--trunk/ext/dl/lib/dl/callback.rb69
-rw-r--r--trunk/ext/dl/lib/dl/cparser.rb109
-rw-r--r--trunk/ext/dl/lib/dl/func.rb141
-rw-r--r--trunk/ext/dl/lib/dl/import.rb215
-rw-r--r--trunk/ext/dl/lib/dl/pack.rb173
-rw-r--r--trunk/ext/dl/lib/dl/stack.rb140
-rw-r--r--trunk/ext/dl/lib/dl/struct.rb213
-rw-r--r--trunk/ext/dl/lib/dl/types.rb40
-rw-r--r--trunk/ext/dl/lib/dl/value.rb108
-rw-r--r--trunk/ext/dl/mkcallback.rb189
-rw-r--r--trunk/ext/dl/test/test_all.rb11
-rw-r--r--trunk/ext/dl/test/test_base.rb52
-rw-r--r--trunk/ext/dl/test/test_dl2.rb111
-rw-r--r--trunk/ext/dl/test/test_func.rb62
-rw-r--r--trunk/ext/dl/test/test_import.rb154
-rw-r--r--trunk/ext/dl/test/test_win32.rb53
-rw-r--r--trunk/ext/dl/win32/extconf.rb3
-rw-r--r--trunk/ext/dl/win32/lib/Win32API.rb28
-rw-r--r--trunk/ext/dl/win32/lib/win32/registry.rb832
-rw-r--r--trunk/ext/dl/win32/lib/win32/resolv.rb370
-rw-r--r--trunk/ext/dl/win32/lib/win32/sspi.rb330
29 files changed, 0 insertions, 5007 deletions
diff --git a/trunk/ext/dl/.cvsignore b/trunk/ext/dl/.cvsignore
deleted file mode 100644
index 6c0b25a1c5..0000000000
--- a/trunk/ext/dl/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-Makefile
-mkmf.log
-dlconfig.h
-dlconfig.rb
-callback.h
-*.func
-*.o
-*~
-*.def
-extconf.h
diff --git a/trunk/ext/dl/cfunc.c b/trunk/ext/dl/cfunc.c
deleted file mode 100644
index 724c290f2f..0000000000
--- a/trunk/ext/dl/cfunc.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* -*- C -*-
- * $Id$
- */
-
-#include <ruby.h>
-#include <errno.h>
-#include "dl.h"
-
-VALUE rb_cDLCFunc;
-
-static ID id_last_error;
-
-static VALUE
-rb_dl_get_last_error(VALUE self)
-{
- return rb_thread_local_aref(rb_thread_current(), id_last_error);
-}
-
-static VALUE
-rb_dl_set_last_error(VALUE self, VALUE val)
-{
- rb_thread_local_aset(rb_thread_current(), id_last_error, val);
- return Qnil;
-}
-
-#if defined(HAVE_WINDOWS_H)
-#include <windows.h>
-static ID id_win32_last_error;
-
-static VALUE
-rb_dl_get_win32_last_error(VALUE self)
-{
- return rb_thread_local_aref(rb_thread_current(), id_win32_last_error);
-}
-
-static VALUE
-rb_dl_set_win32_last_error(VALUE self, VALUE val)
-{
- rb_thread_local_aset(rb_thread_current(), id_win32_last_error, val);
- return Qnil;
-}
-#endif
-
-
-void
-dlcfunc_free(struct cfunc_data *data)
-{
- if( data->name ){
- xfree(data->name);
- }
- xfree(data);
-}
-
-VALUE
-rb_dlcfunc_new(void (*func)(), int type, const char *name, ID calltype)
-{
- VALUE val;
- struct cfunc_data *data;
-
- rb_secure(4);
- if( func ){
- val = Data_Make_Struct(rb_cDLCFunc, struct cfunc_data, 0, dlcfunc_free, data);
- data->ptr = func;
- data->name = name ? strdup(name) : NULL;
- data->type = type;
- data->calltype = calltype;
- }
- else{
- val = Qnil;
- }
-
- return val;
-}
-
-void *
-rb_dlcfunc2ptr(VALUE val)
-{
- struct cfunc_data *data;
- void * func;
-
- if( rb_obj_is_kind_of(val, rb_cDLCFunc) ){
- Data_Get_Struct(val, struct cfunc_data, data);
- func = data->ptr;
- }
- else if( val == Qnil ){
- func = NULL;
- }
- else{
- rb_raise(rb_eTypeError, "DL::CFunc was expected");
- }
-
- return func;
-}
-
-VALUE
-rb_dlcfunc_s_allocate(VALUE klass)
-{
- VALUE obj;
- struct cfunc_data *data;
-
- obj = Data_Make_Struct(klass, struct cfunc_data, 0, dlcfunc_free, data);
- data->ptr = 0;
- data->name = 0;
- data->type = 0;
- data->calltype = CFUNC_CDECL;
-
- return obj;
-}
-
-VALUE
-rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self)
-{
- VALUE addr, name, type, calltype;
- struct cfunc_data *data;
- void *saddr;
- const char *sname;
-
- rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype);
-
- saddr = (void*)(NUM2PTR(rb_Integer(addr)));
- sname = NIL_P(name) ? NULL : StringValuePtr(name);
-
- Data_Get_Struct(self, struct cfunc_data, data);
- if( data->name ) xfree(data->name);
- data->ptr = saddr;
- data->name = sname ? strdup(sname) : 0;
- data->type = (type == Qnil) ? DLTYPE_VOID : NUM2INT(type);
- data->calltype = (calltype == Qnil) ? CFUNC_CDECL : SYM2ID(calltype);
-
- return Qnil;
-}
-
-VALUE
-rb_dlcfunc_name(VALUE self)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- return cfunc->name ? rb_tainted_str_new2(cfunc->name) : Qnil;
-}
-
-VALUE
-rb_dlcfunc_ctype(VALUE self)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- return INT2NUM(cfunc->type);
-}
-
-VALUE
-rb_dlcfunc_set_ctype(VALUE self, VALUE ctype)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- cfunc->type = NUM2INT(ctype);
- return ctype;
-}
-
-VALUE
-rb_dlcfunc_calltype(VALUE self)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- return ID2SYM(cfunc->calltype);
-}
-
-VALUE
-rb_dlcfunc_set_calltype(VALUE self, VALUE sym)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- cfunc->calltype = SYM2ID(sym);
- return sym;
-}
-
-
-VALUE
-rb_dlcfunc_ptr(VALUE self)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- return PTR2NUM(cfunc->ptr);
-}
-
-VALUE
-rb_dlcfunc_set_ptr(VALUE self, VALUE addr)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- cfunc->ptr = NUM2PTR(addr);
-
- return Qnil;
-}
-
-VALUE
-rb_dlcfunc_inspect(VALUE self)
-{
- VALUE val;
- char *str;
- int str_size;
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
-
- str_size = (cfunc->name ? strlen(cfunc->name) : 0) + 100;
- str = ruby_xmalloc(str_size);
- snprintf(str, str_size - 1,
- "#<DL::CFunc:%p ptr=%p type=%d name='%s'>",
- cfunc,
- cfunc->ptr,
- cfunc->type,
- cfunc->name ? cfunc->name : "");
- val = rb_tainted_str_new2(str);
- ruby_xfree(str);
-
- return val;
-}
-
-
-# define DECL_FUNC_CDECL(f,ret,args) ret (FUNC_CDECL(*f))(args)
-# define DECL_FUNC_STDCALL(f,ret,args) ret (FUNC_STDCALL(*f))(args)
-
-#define CALL_CASE switch( RARRAY_LEN(ary) ){ \
- CASE(0); break; \
- CASE(1); break; CASE(2); break; CASE(3); break; CASE(4); break; CASE(5); break; \
- CASE(6); break; CASE(7); break; CASE(8); break; CASE(9); break; CASE(10);break; \
- CASE(11);break; CASE(12);break; CASE(13);break; CASE(14);break; CASE(15);break; \
- CASE(16);break; CASE(17);break; CASE(18);break; CASE(19);break; CASE(20);break; \
- default: rb_raise(rb_eArgError, "too many arguments"); \
-}
-
-
-VALUE
-rb_dlcfunc_call(VALUE self, VALUE ary)
-{
- struct cfunc_data *cfunc;
- int i;
- DLSTACK_TYPE stack[DLSTACK_SIZE];
- VALUE result = Qnil;
-
- rb_secure_update(self);
-
- memset(stack, 0, sizeof(DLSTACK_TYPE) * DLSTACK_SIZE);
- Check_Type(ary, T_ARRAY);
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
-
- if( cfunc->ptr == 0 ){
- rb_raise(rb_eDLError, "can't call null-function");
- return Qnil;
- }
-
- for( i = 0; i < RARRAY_LEN(ary); i++ ){
- if( i >= DLSTACK_SIZE ){
- rb_raise(rb_eDLError, "too many arguments (stack overflow)");
- }
- rb_check_safe_obj(RARRAY_PTR(ary)[i]);
- stack[i] = NUM2LONG(RARRAY_PTR(ary)[i]);
- }
-
- /* calltype == CFUNC_CDECL */
- if( cfunc->calltype == CFUNC_CDECL ){
- switch( cfunc->type ){
- case DLTYPE_VOID:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \
- f(DLSTACK_ARGS##n(stack)); \
- result = Qnil; \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_VOIDP:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,void*,DLSTACK_PROTO##n) = cfunc->ptr; \
- void * ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = PTR2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_CHAR:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,char,DLSTACK_PROTO##n) = cfunc->ptr; \
- char ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = CHR2FIX(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_SHORT:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,short,DLSTACK_PROTO##n) = cfunc->ptr; \
- short ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = INT2NUM((int)ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_INT:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,int,DLSTACK_PROTO##n) = cfunc->ptr; \
- int ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = INT2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_LONG:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,long,DLSTACK_PROTO##n) = cfunc->ptr; \
- long ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = LONG2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
-#if HAVE_LONG_LONG /* used in ruby.h */
- case DLTYPE_LONG_LONG:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,LONG_LONG,DLSTACK_PROTO) = cfunc->ptr; \
- LONG_LONG ret; \
- ret = f(DLSTACK_ARGS(stack)); \
- result = LL2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
-#endif
- case DLTYPE_FLOAT:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,float,DLSTACK_PROTO) = cfunc->ptr; \
- float ret; \
- ret = f(DLSTACK_ARGS(stack)); \
- result = rb_float_new(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_DOUBLE:
-#define CASE(n) case n: { \
- DECL_FUNC_CDECL(f,double,DLSTACK_PROTO) = cfunc->ptr; \
- double ret; \
- ret = f(DLSTACK_ARGS(stack)); \
- result = rb_float_new(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- default:
- rb_raise(rb_eDLTypeError, "unknown type %d", cfunc->type);
- }
- }
- else if( cfunc->calltype == CFUNC_STDCALL ){
- /* calltype == CFUNC_STDCALL */
- switch( cfunc->type ){
- case DLTYPE_VOID:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \
- f(DLSTACK_ARGS##n(stack)); \
- result = Qnil; \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_VOIDP:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,void*,DLSTACK_PROTO##n) = cfunc->ptr; \
- void * ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = PTR2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_CHAR:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,char,DLSTACK_PROTO##n) = cfunc->ptr; \
- char ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = CHR2FIX(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_SHORT:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,short,DLSTACK_PROTO##n) = cfunc->ptr; \
- short ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = INT2NUM((int)ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_INT:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,int,DLSTACK_PROTO##n) = cfunc->ptr; \
- int ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = INT2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_LONG:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,long,DLSTACK_PROTO##n) = cfunc->ptr; \
- long ret; \
- ret = f(DLSTACK_ARGS##n(stack)); \
- result = LONG2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
-#if HAVE_LONG_LONG /* used in ruby.h */
- case DLTYPE_LONG_LONG:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,LONG_LONG,DLSTACK_PROTO) = cfunc->ptr; \
- LONG_LONG ret; \
- ret = f(DLSTACK_ARGS(stack)); \
- result = LL2NUM(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
-#endif
- case DLTYPE_FLOAT:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,float,DLSTACK_PROTO) = cfunc->ptr; \
- float ret; \
- ret = f(DLSTACK_ARGS(stack)); \
- result = rb_float_new(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- case DLTYPE_DOUBLE:
-#define CASE(n) case n: { \
- DECL_FUNC_STDCALL(f,double,DLSTACK_PROTO) = cfunc->ptr; \
- double ret; \
- ret = f(DLSTACK_ARGS(stack)); \
- result = rb_float_new(ret); \
-}
- CALL_CASE;
-#undef CASE
- break;
- default:
- rb_raise(rb_eDLTypeError, "unknown type %d", cfunc->type);
- }
- }
- else{
- rb_raise(rb_eDLError,
-#ifndef LONG_LONG_VALUE
- "unsupported call type: %lx",
-#else
- "unsupported call type: %llx",
-#endif
- cfunc->calltype);
- }
-
- rb_dl_set_last_error(self, INT2NUM(errno));
-#if defined(HAVE_WINDOWS_H)
- rb_dl_set_win32_last_error(self, INT2NUM(GetLastError()));
-#endif
-
- return result;
-}
-
-VALUE
-rb_dlcfunc_to_i(VALUE self)
-{
- struct cfunc_data *cfunc;
-
- Data_Get_Struct(self, struct cfunc_data, cfunc);
- return PTR2NUM(cfunc->ptr);
-}
-
-void
-Init_dlcfunc()
-{
- id_last_error = rb_intern("__DL2_LAST_ERROR__");
-#if defined(HAVE_WINDOWS_H)
- id_win32_last_error = rb_intern("__DL2_WIN32_LAST_ERROR__");
-#endif
- rb_cDLCFunc = rb_define_class_under(rb_mDL, "CFunc", rb_cObject);
- rb_define_alloc_func(rb_cDLCFunc, rb_dlcfunc_s_allocate);
- rb_define_module_function(rb_cDLCFunc, "last_error", rb_dl_get_last_error, 0);
-#if defined(HAVE_WINDOWS_H)
- rb_define_module_function(rb_cDLCFunc, "win32_last_error", rb_dl_get_win32_last_error, 0);
-#endif
- rb_define_method(rb_cDLCFunc, "initialize", rb_dlcfunc_initialize, -1);
- rb_define_method(rb_cDLCFunc, "call", rb_dlcfunc_call, 1);
- rb_define_method(rb_cDLCFunc, "[]", rb_dlcfunc_call, 1);
- rb_define_method(rb_cDLCFunc, "name", rb_dlcfunc_name, 0);
- rb_define_method(rb_cDLCFunc, "ctype", rb_dlcfunc_ctype, 0);
- rb_define_method(rb_cDLCFunc, "ctype=", rb_dlcfunc_set_ctype, 1);
- rb_define_method(rb_cDLCFunc, "calltype", rb_dlcfunc_calltype, 0);
- rb_define_method(rb_cDLCFunc, "calltype=", rb_dlcfunc_set_calltype, 1);
- rb_define_method(rb_cDLCFunc, "ptr", rb_dlcfunc_ptr, 0);
- rb_define_method(rb_cDLCFunc, "ptr=", rb_dlcfunc_set_ptr, 1);
- rb_define_method(rb_cDLCFunc, "inspect", rb_dlcfunc_inspect, 0);
- rb_define_method(rb_cDLCFunc, "to_s", rb_dlcfunc_inspect, 0);
- rb_define_method(rb_cDLCFunc, "to_i", rb_dlcfunc_to_i, 0);
-}
diff --git a/trunk/ext/dl/cptr.c b/trunk/ext/dl/cptr.c
deleted file mode 100644
index 7487b0cf55..0000000000
--- a/trunk/ext/dl/cptr.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/* -*- C -*-
- * $Id$
- */
-
-#include <ruby/ruby.h>
-#include <ruby/io.h>
-#include <ctype.h>
-#include "dl.h"
-
-VALUE rb_cDLCPtr;
-
-static ID id_to_ptr;
-
-static void
-dlptr_free(struct ptr_data *data)
-{
- if (data->ptr) {
- if (data->free) {
- (*(data->free))(data->ptr);
- }
- }
-}
-
-static void
-dlptr_mark(struct ptr_data *data)
-{
-}
-
-void
-dlptr_init(VALUE val)
-{
- struct ptr_data *data;
-
- Data_Get_Struct(val, struct ptr_data, data);
- 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);
- val = Data_Make_Struct(klass, struct ptr_data,
- 0, dlptr_free, data);
- data->ptr = ptr;
- data->free = func;
- data->size = size;
- dlptr_init(val);
-
- return val;
-}
-
-VALUE
-rb_dlptr_new(void *ptr, long size, freefunc_t func)
-{
- return rb_dlptr_new2(rb_cDLCPtr, ptr, size, func);
-}
-
-VALUE
-rb_dlptr_malloc(long size, freefunc_t func)
-{
- void *ptr;
-
- rb_secure(4);
- ptr = ruby_xmalloc((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_cDLCPtr)) {
- Data_Get_Struct(val, struct ptr_data, data);
- ptr = data->ptr;
- }
- else if (val == Qnil) {
- 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, dlptr_mark, dlptr_free, data);
- data->ptr = 0;
- data->size = 0;
- data->free = 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;
-
- switch (rb_scan_args(argc, argv, "12", &ptr, &size, &sym)) {
- case 1:
- p = (void*)(NUM2PTR(rb_Integer(ptr)));
- break;
- case 2:
- p = (void*)(NUM2PTR(rb_Integer(ptr)));
- s = NUM2LONG(size);
- break;
- case 3:
- p = (void*)(NUM2PTR(rb_Integer(ptr)));
- s = NUM2LONG(size);
- f = NIL_P(sym) ? NULL : RCFUNC_DATA(sym)->ptr;
- break;
- default:
- rb_bug("rb_dlptr_initialize");
- }
-
- if (p) {
- Data_Get_Struct(self, struct ptr_data, data);
- if (data->ptr && 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;
- }
-
- return Qnil;
-}
-
-static VALUE
-rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
-{
- VALUE size, sym, obj;
- int s;
- freefunc_t f;
-
- switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
- case 1:
- s = NUM2LONG(size);
- f = NULL;
- break;
- case 2:
- s = NUM2LONG(size);
- f = RCFUNC_DATA(sym)->ptr;
- 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 PTR2NUM(data->ptr);
-}
-
-VALUE
-rb_dlptr_to_value(VALUE self)
-{
- struct ptr_data *data;
- Data_Get_Struct(self, struct ptr_data, data);
- return (VALUE)(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;
- extern VALUE rb_cDLCFunc;
-
- Data_Get_Struct(self, struct ptr_data, data);
- if( rb_obj_is_kind_of(val, rb_cDLCFunc) == Qtrue ){
- data->free = RCFUNC_DATA(val)->ptr;
- }
- else{
- data->free = NUM2PTR(rb_Integer(val));
- }
-
- return Qnil;
-}
-
-VALUE
-rb_dlptr_free_get(VALUE self)
-{
- struct ptr_data *pdata;
-
- Data_Get_Struct(self, struct ptr_data, pdata);
-
- return rb_dlcfunc_new(pdata->free, DLTYPE_VOID, "free<anonymous>", CFUNC_CDECL);
-}
-
-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:%p ptr=%p size=%ld free=%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 PTR2NUM((long)ptr1 - (long)ptr2);
-}
-
-VALUE
-rb_dlptr_plus(VALUE self, VALUE other)
-{
- void *ptr;
- long num, size;
-
- ptr = rb_dlptr2cptr(self);
- size = RPTR_DATA(self)->size;
- num = NUM2LONG(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 = RPTR_DATA(self)->size;
- num = NUM2LONG(other);
- return rb_dlptr_new((char *)ptr - num, size + num, 0);
-}
-
-VALUE
-rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
-{
- VALUE arg0, arg1;
- VALUE retval = Qnil;
- size_t offset, len;
-
- switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
- case 1:
- offset = NUM2ULONG(arg0);
- retval = INT2NUM(*((char*)RPTR_DATA(self)->ptr + offset));
- break;
- case 2:
- offset = NUM2ULONG(arg0);
- len = NUM2ULONG(arg1);
- retval = rb_tainted_str_new((char *)RPTR_DATA(self)->ptr + offset, len);
- break;
- default:
- rb_bug("rb_dlptr_aref()");
- }
- return retval;
-}
-
-VALUE
-rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
-{
- VALUE arg0, arg1, arg2;
- VALUE retval = Qnil;
- size_t offset, len;
- void *mem;
-
- switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
- case 2:
- offset = NUM2ULONG(arg0);
- ((char*)RPTR_DATA(self)->ptr)[offset] = NUM2UINT(arg1);
- retval = arg1;
- break;
- case 3:
- offset = NUM2ULONG(arg0);
- len = NUM2ULONG(arg1);
- if( TYPE(arg2) == T_STRING ){
- mem = StringValuePtr(arg2);
- }
- else if( rb_obj_is_kind_of(arg2, rb_cDLCPtr) ){
- mem = rb_dlptr2cptr(arg2);
- }
- else{
- mem = NUM2PTR(arg2);
- }
- memcpy((char *)RPTR_DATA(self)->ptr + offset, mem, len);
- retval = arg2;
- break;
- default:
- rb_bug("rb_dlptr_aset()");
- }
- return retval;
-}
-
-VALUE
-rb_dlptr_size(int argc, VALUE argv[], VALUE self)
-{
- VALUE size;
-
- if (rb_scan_args(argc, argv, "01", &size) == 0){
- return LONG2NUM(RPTR_DATA(self)->size);
- }
- else{
- RPTR_DATA(self)->size = NUM2LONG(size);
- return size;
- }
-}
-
-VALUE
-rb_dlptr_s_to_ptr(VALUE self, VALUE val)
-{
- VALUE ptr;
-
- if (rb_obj_is_kind_of(val, rb_cIO) == Qtrue){
- rb_io_t *fptr;
- FILE *fp;
- GetOpenFile(val, fptr);
- fp = rb_io_stdio_file(fptr);
- ptr = rb_dlptr_new(fp, 0, NULL);
- }
- else if (rb_obj_is_kind_of(val, rb_cString) == Qtrue){
- char *str = StringValuePtr(val);
- ptr = rb_dlptr_new(str, RSTRING_LEN(val), NULL);
- }
- else if (rb_respond_to(val, id_to_ptr)){
- VALUE vptr = rb_funcall(val, id_to_ptr, 0);
- if (rb_obj_is_kind_of(vptr, rb_cDLCPtr)){
- ptr = vptr;
- }
- else{
- rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
- }
- }
- else{
- ptr = rb_dlptr_new(NUM2PTR(rb_Integer(val)), 0, NULL);
- }
- OBJ_INFECT(ptr, val);
- return ptr;
-}
-
-void
-Init_dlptr()
-{
- id_to_ptr = rb_intern("to_ptr");
-
- rb_cDLCPtr = rb_define_class_under(rb_mDL, "CPtr", rb_cObject);
- rb_define_alloc_func(rb_cDLCPtr, rb_dlptr_s_allocate);
- rb_define_singleton_method(rb_cDLCPtr, "malloc", rb_dlptr_s_malloc, -1);
- rb_define_singleton_method(rb_cDLCPtr, "to_ptr", rb_dlptr_s_to_ptr, 1);
- rb_define_singleton_method(rb_cDLCPtr, "[]", rb_dlptr_s_to_ptr, 1);
- rb_define_method(rb_cDLCPtr, "initialize", rb_dlptr_initialize, -1);
- rb_define_method(rb_cDLCPtr, "free=", rb_dlptr_free_set, 1);
- rb_define_method(rb_cDLCPtr, "free", rb_dlptr_free_get, 0);
- rb_define_method(rb_cDLCPtr, "to_i", rb_dlptr_to_i, 0);
- rb_define_method(rb_cDLCPtr, "to_value", rb_dlptr_to_value, 0);
- rb_define_method(rb_cDLCPtr, "ptr", rb_dlptr_ptr, 0);
- rb_define_method(rb_cDLCPtr, "+@", rb_dlptr_ptr, 0);
- rb_define_method(rb_cDLCPtr, "ref", rb_dlptr_ref, 0);
- rb_define_method(rb_cDLCPtr, "-@", rb_dlptr_ref, 0);
- rb_define_method(rb_cDLCPtr, "null?", rb_dlptr_null_p, 0);
- rb_define_method(rb_cDLCPtr, "to_s", rb_dlptr_to_s, -1);
- rb_define_method(rb_cDLCPtr, "to_str", rb_dlptr_to_str, -1);
- rb_define_method(rb_cDLCPtr, "inspect", rb_dlptr_inspect, 0);
- rb_define_method(rb_cDLCPtr, "<=>", rb_dlptr_cmp, 1);
- rb_define_method(rb_cDLCPtr, "==", rb_dlptr_eql, 1);
- rb_define_method(rb_cDLCPtr, "eql?", rb_dlptr_eql, 1);
- rb_define_method(rb_cDLCPtr, "+", rb_dlptr_plus, 1);
- rb_define_method(rb_cDLCPtr, "-", rb_dlptr_minus, 1);
- rb_define_method(rb_cDLCPtr, "[]", rb_dlptr_aref, -1);
- rb_define_method(rb_cDLCPtr, "[]=", rb_dlptr_aset, -1);
- rb_define_method(rb_cDLCPtr, "size", rb_dlptr_size, -1);
- rb_define_method(rb_cDLCPtr, "size=", rb_dlptr_size, -1);
-
- rb_define_const(rb_mDL, "NULL", rb_dlptr_new(0, 0, 0));
-}
diff --git a/trunk/ext/dl/depend b/trunk/ext/dl/depend
deleted file mode 100644
index fe89a9fae3..0000000000
--- a/trunk/ext/dl/depend
+++ /dev/null
@@ -1,11 +0,0 @@
-cfunc.o: cfunc.c dl.h $(hdrdir)/ruby.h
-
-cptr.o: cptr.c dl.h $(hdrdir)/ruby.h $(hdrdir)/io.h
-
-handle.o: handle.c dl.h $(hdrdir)/ruby.h
-
-dl.o: dl.c dl.h callback.h $(hdrdir)/ruby.h $(hdrdir)/io.h
-
-callback.h: $(srcdir)/mkcallback.rb dl.h
- @echo "generating callback.h"
- @$(RUBY) $(srcdir)/mkcallback.rb $(srcdir)/dl.h > $@
diff --git a/trunk/ext/dl/dl.c b/trunk/ext/dl/dl.c
deleted file mode 100644
index 0427dfb3f3..0000000000
--- a/trunk/ext/dl/dl.c
+++ /dev/null
@@ -1,137 +0,0 @@
-#include <ruby/ruby.h>
-#include <ruby/io.h>
-#include <ctype.h>
-#include "dl.h"
-
-VALUE rb_mDL;
-VALUE rb_eDLError;
-VALUE rb_eDLTypeError;
-
-ID rbdl_id_cdecl;
-ID rbdl_id_stdcall;
-
-VALUE
-rb_dl_dlopen(int argc, VALUE argv[], VALUE self)
-{
- rb_secure(2);
- return rb_class_new_instance(argc, argv, rb_cDLHandle);
-}
-
-VALUE
-rb_dl_malloc(VALUE self, VALUE size)
-{
- void *ptr;
-
- rb_secure(4);
- ptr = (void*)ruby_xmalloc(NUM2INT(size));
- return PTR2NUM(ptr);
-}
-
-VALUE
-rb_dl_realloc(VALUE self, VALUE addr, VALUE size)
-{
- void *ptr = NUM2PTR(addr);
-
- rb_secure(4);
- ptr = (void*)ruby_xrealloc(ptr, NUM2INT(size));
- return PTR2NUM(ptr);
-}
-
-VALUE
-rb_dl_free(VALUE self, VALUE addr)
-{
- void *ptr = NUM2PTR(addr);
-
- rb_secure(4);
- ruby_xfree(ptr);
- return Qnil;
-}
-
-VALUE
-rb_dl_ptr2value(VALUE self, VALUE addr)
-{
- rb_secure(4);
- return (VALUE)NUM2PTR(addr);
-}
-
-VALUE
-rb_dl_value2ptr(VALUE self, VALUE val)
-{
- return PTR2NUM((void*)val);
-}
-
-#include "callback.h"
-
-void
-Init_dl()
-{
- void Init_dlhandle();
- void Init_dlcfunc();
- void Init_dlptr();
-
- rbdl_id_cdecl = rb_intern("cdecl");
- rbdl_id_stdcall = rb_intern("stdcall");
-
- 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);
-
- rb_define_const(rb_mDL, "MAX_CALLBACK", INT2NUM(MAX_CALLBACK));
- rb_define_const(rb_mDL, "DLSTACK_SIZE", INT2NUM(DLSTACK_SIZE));
-
- rb_dl_init_callbacks();
-
- 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, "TYPE_VOID", INT2NUM(DLTYPE_VOID));
- rb_define_const(rb_mDL, "TYPE_VOIDP", INT2NUM(DLTYPE_VOIDP));
- rb_define_const(rb_mDL, "TYPE_CHAR", INT2NUM(DLTYPE_CHAR));
- rb_define_const(rb_mDL, "TYPE_SHORT", INT2NUM(DLTYPE_SHORT));
- rb_define_const(rb_mDL, "TYPE_INT", INT2NUM(DLTYPE_INT));
- rb_define_const(rb_mDL, "TYPE_LONG", INT2NUM(DLTYPE_LONG));
-#if HAVE_LONG_LONG
- rb_define_const(rb_mDL, "TYPE_LONG_LONG", INT2NUM(DLTYPE_LONG_LONG));
-#endif
- rb_define_const(rb_mDL, "TYPE_FLOAT", INT2NUM(DLTYPE_FLOAT));
- rb_define_const(rb_mDL, "TYPE_DOUBLE", INT2NUM(DLTYPE_DOUBLE));
-
- rb_define_const(rb_mDL, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
- rb_define_const(rb_mDL, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
- rb_define_const(rb_mDL, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
- rb_define_const(rb_mDL, "ALIGN_INT", INT2NUM(ALIGN_INT));
- rb_define_const(rb_mDL, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
-#if HAVE_LONG_LONG
- rb_define_const(rb_mDL, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
-#endif
- rb_define_const(rb_mDL, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
- rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
-
- rb_define_const(rb_mDL, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
- rb_define_const(rb_mDL, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
- rb_define_const(rb_mDL, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
- rb_define_const(rb_mDL, "SIZEOF_INT", INT2NUM(sizeof(int)));
- rb_define_const(rb_mDL, "SIZEOF_LONG", INT2NUM(sizeof(long)));
-#if HAVE_LONG_LONG
- rb_define_const(rb_mDL, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
-#endif
- rb_define_const(rb_mDL, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
- rb_define_const(rb_mDL, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
-
- rb_define_module_function(rb_mDL, "dlwrap", rb_dl_value2ptr, 1);
- rb_define_module_function(rb_mDL, "dlunwrap", rb_dl_ptr2value, 1);
-
- rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1);
- rb_define_module_function(rb_mDL, "malloc", rb_dl_malloc, 1);
- rb_define_module_function(rb_mDL, "realloc", rb_dl_realloc, 2);
- rb_define_module_function(rb_mDL, "free", rb_dl_free, 1);
-
- rb_define_const(rb_mDL, "RUBY_FREE", PTR2NUM(ruby_xfree));
- rb_define_const(rb_mDL, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
- rb_define_const(rb_mDL, "BUILD_RUBY_VERSION", rb_str_new2(RUBY_VERSION));
-
- Init_dlhandle();
- Init_dlcfunc();
- Init_dlptr();
-}
diff --git a/trunk/ext/dl/dl.h b/trunk/ext/dl/dl.h
deleted file mode 100644
index 7b8ad077ae..0000000000
--- a/trunk/ext/dl/dl.h
+++ /dev/null
@@ -1,190 +0,0 @@
-#ifndef RUBY_DL_H
-#define RUBY_DL_H
-
-#include <ruby.h>
-
-#if !defined(FUNC_CDECL)
-# define FUNC_CDECL(x) x
-#endif
-#if !defined(FUNC_STDCALL)
-# define FUNC_STDCALL(x) x
-#endif
-
-#if defined(HAVE_DLFCN_H)
-# include <dlfcn.h>
-# /* 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 <windows.h>
-# 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
-
-#define MAX_CALLBACK 5
-#define DLSTACK_TYPE long
-#define DLSTACK_SIZE (20)
-#define DLSTACK_PROTO \
- DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,\
- DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,\
- DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,\
- DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE
-#define DLSTACK_ARGS(stack) \
- 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],\
- stack[15],stack[16],stack[17],stack[18],stack[19]
-
-#define DLSTACK_PROTO0
-#define DLSTACK_PROTO1 DLSTACK_TYPE
-#define DLSTACK_PROTO2 DLSTACK_PROTO1, DLSTACK_TYPE
-#define DLSTACK_PROTO3 DLSTACK_PROTO2, DLSTACK_TYPE
-#define DLSTACK_PROTO4 DLSTACK_PROTO3, DLSTACK_TYPE
-#define DLSTACK_PROTO4 DLSTACK_PROTO3, DLSTACK_TYPE
-#define DLSTACK_PROTO5 DLSTACK_PROTO4, DLSTACK_TYPE
-#define DLSTACK_PROTO6 DLSTACK_PROTO5, DLSTACK_TYPE
-#define DLSTACK_PROTO7 DLSTACK_PROTO6, DLSTACK_TYPE
-#define DLSTACK_PROTO8 DLSTACK_PROTO7, DLSTACK_TYPE
-#define DLSTACK_PROTO9 DLSTACK_PROTO8, DLSTACK_TYPE
-#define DLSTACK_PROTO10 DLSTACK_PROTO9, DLSTACK_TYPE
-#define DLSTACK_PROTO11 DLSTACK_PROTO10, DLSTACK_TYPE
-#define DLSTACK_PROTO12 DLSTACK_PROTO11, DLSTACK_TYPE
-#define DLSTACK_PROTO13 DLSTACK_PROTO12, DLSTACK_TYPE
-#define DLSTACK_PROTO14 DLSTACK_PROTO13, DLSTACK_TYPE
-#define DLSTACK_PROTO14 DLSTACK_PROTO13, DLSTACK_TYPE
-#define DLSTACK_PROTO15 DLSTACK_PROTO14, DLSTACK_TYPE
-#define DLSTACK_PROTO16 DLSTACK_PROTO15, DLSTACK_TYPE
-#define DLSTACK_PROTO17 DLSTACK_PROTO16, DLSTACK_TYPE
-#define DLSTACK_PROTO18 DLSTACK_PROTO17, DLSTACK_TYPE
-#define DLSTACK_PROTO19 DLSTACK_PROTO18, DLSTACK_TYPE
-#define DLSTACK_PROTO20 DLSTACK_PROTO19, DLSTACK_TYPE
-
-#define DLSTACK_ARGS0(stack)
-#define DLSTACK_ARGS1(stack) stack[0]
-#define DLSTACK_ARGS2(stack) DLSTACK_ARGS1(stack), stack[1]
-#define DLSTACK_ARGS3(stack) DLSTACK_ARGS2(stack), stack[2]
-#define DLSTACK_ARGS4(stack) DLSTACK_ARGS3(stack), stack[3]
-#define DLSTACK_ARGS5(stack) DLSTACK_ARGS4(stack), stack[4]
-#define DLSTACK_ARGS6(stack) DLSTACK_ARGS5(stack), stack[5]
-#define DLSTACK_ARGS7(stack) DLSTACK_ARGS6(stack), stack[6]
-#define DLSTACK_ARGS8(stack) DLSTACK_ARGS7(stack), stack[7]
-#define DLSTACK_ARGS9(stack) DLSTACK_ARGS8(stack), stack[8]
-#define DLSTACK_ARGS10(stack) DLSTACK_ARGS9(stack), stack[9]
-#define DLSTACK_ARGS11(stack) DLSTACK_ARGS10(stack), stack[10]
-#define DLSTACK_ARGS12(stack) DLSTACK_ARGS11(stack), stack[11]
-#define DLSTACK_ARGS13(stack) DLSTACK_ARGS12(stack), stack[12]
-#define DLSTACK_ARGS14(stack) DLSTACK_ARGS13(stack), stack[13]
-#define DLSTACK_ARGS15(stack) DLSTACK_ARGS14(stack), stack[14]
-#define DLSTACK_ARGS16(stack) DLSTACK_ARGS15(stack), stack[15]
-#define DLSTACK_ARGS17(stack) DLSTACK_ARGS16(stack), stack[16]
-#define DLSTACK_ARGS18(stack) DLSTACK_ARGS17(stack), stack[17]
-#define DLSTACK_ARGS19(stack) DLSTACK_ARGS18(stack), stack[18]
-#define DLSTACK_ARGS20(stack) DLSTACK_ARGS19(stack), stack[19]
-
-extern VALUE rb_mDL;
-extern VALUE rb_cDLHandle;
-extern VALUE rb_cDLSymbol;
-extern VALUE rb_eDLError;
-extern VALUE rb_eDLTypeError;
-
-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;
-#if HAVE_LONG_LONG
-typedef struct { char c; LONG_LONG x; } s_long_long;
-#endif
-
-#define ALIGN_VOIDP (sizeof(s_voidp) - sizeof(void *))
-#define ALIGN_SHORT (sizeof(s_short) - sizeof(short))
-#define ALIGN_CHAR (1)
-#define ALIGN_INT (sizeof(s_int) - sizeof(int))
-#define ALIGN_LONG (sizeof(s_long) - sizeof(long))
-#if HAVE_LONG_LONG
-#define ALIGN_LONG_LONG (sizeof(s_long_long) - sizeof(LONG_LONG))
-#endif
-#define ALIGN_FLOAT (sizeof(s_float) - sizeof(float))
-#define ALIGN_DOUBLE (sizeof(s_double) - sizeof(double))
-
-#define DLALIGN(ptr,offset,align) {\
- while( (((unsigned long)((char *)ptr + offset)) % align) != 0 ) offset++;\
-}
-
-
-#define DLTYPE_VOID 0
-#define DLTYPE_VOIDP 1
-#define DLTYPE_CHAR 2
-#define DLTYPE_SHORT 3
-#define DLTYPE_INT 4
-#define DLTYPE_LONG 5
-#if HAVE_LONG_LONG
-#define DLTYPE_LONG_LONG 6
-#endif
-#define DLTYPE_FLOAT 7
-#define DLTYPE_DOUBLE 8
-#define MAX_DLTYPE 9
-
-#if SIZEOF_VOIDP == SIZEOF_LONG
-# define PTR2NUM(x) (ULONG2NUM((unsigned long)(x)))
-# define NUM2PTR(x) ((void*)(NUM2ULONG(x)))
-#else
-/* # error --->> Ruby/DL2 requires sizeof(void*) == sizeof(long) to be compiled. <<--- */
-# define PTR2NUM(x) (ULL2NUM((unsigned long long)(x)))
-# define NUM2PTR(x) ((void*)(NUM2ULL(x)))
-#endif
-
-#define BOOL2INT(x) ((x == Qtrue)?1:0)
-#define INT2BOOL(x) (x?Qtrue:Qfalse)
-
-typedef void (*freefunc_t)(void*);
-
-struct dl_handle {
- void *ptr;
- int open;
- int enable_close;
-};
-
-
-struct cfunc_data {
- void *ptr;
- char *name;
- int type;
- ID calltype;
-};
-extern ID rbdl_id_cdecl;
-extern ID rbdl_id_stdcall;
-#define CFUNC_CDECL (rbdl_id_cdecl)
-#define CFUNC_STDCALL (rbdl_id_stdcall)
-
-struct ptr_data {
- void *ptr;
- long size;
- freefunc_t free;
-};
-
-#define RDL_HANDLE(obj) ((struct dl_handle *)(DATA_PTR(obj)))
-#define RCFUNC_DATA(obj) ((struct cfunc_data *)(DATA_PTR(obj)))
-#define RPTR_DATA(obj) ((struct ptr_data *)(DATA_PTR(obj)))
-
-VALUE rb_dlcfunc_new(void (*func)(), int dltype, const char * name, ID calltype);
-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);
-
-#endif
diff --git a/trunk/ext/dl/extconf.rb b/trunk/ext/dl/extconf.rb
deleted file mode 100644
index abd8d8f781..0000000000
--- a/trunk/ext/dl/extconf.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-require 'mkmf'
-
-if( RbConfig::CONFIG['CC'] =~ /gcc/ )
- $CFLAGS << " -fno-defer-pop -fno-omit-frame-pointer"
-end
-
-$INSTALLFILES = [
- ["dl.h", "$(HDRDIR)"],
-]
-$distcleanfiles << "callback.h"
-
-
-check = true
-if( have_header("dlfcn.h") )
- have_library("dl")
- check &&= have_func("dlopen")
- check &&= have_func("dlclose")
- check &&= have_func("dlsym")
- have_func("dlerror")
-elsif( have_header("windows.h") )
- check &&= have_func("LoadLibrary")
- check &&= have_func("FreeLibrary")
- check &&= have_func("GetProcAddress")
-else
- check = false
-end
-
-if check
- $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"]
- create_makefile("dl")
-end
diff --git a/trunk/ext/dl/handle.c b/trunk/ext/dl/handle.c
deleted file mode 100644
index 24269dfd78..0000000000
--- a/trunk/ext/dl/handle.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* -*- C -*-
- * $Id$
- */
-
-#include <ruby.h>
-#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, "02", &lib, &flag) ){
- case 0:
- clib = NULL;
- cflag = RTLD_LAZY | RTLD_GLOBAL;
- break;
- 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_eDLError, "%s", err);
- }
-#else
- if( !ptr ){
- err = dlerror();
- rb_raise(rb_eDLError, "%s", 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 PTR2NUM(dlhandle);
-}
-
-VALUE
-rb_dlhandle_sym(VALUE self, VALUE sym)
-{
- void (*func)();
- struct dl_handle *dlhandle;
- void *handle;
- const char *name;
- const char *err;
- int i;
-
-#if defined(HAVE_DLERROR)
-# define CHECK_DLERROR if( err = dlerror() ){ func = 0; }
-#else
-# define CHECK_DLERROR
-#endif
-
- rb_secure(2);
-
- if( sym == Qnil ){
-#if defined(RTLD_NEXT)
- name = RTLD_NEXT;
-#else
- name = NULL;
-#endif
- }
- else{
- name = StringValuePtr(sym);
- }
-
-
- Data_Get_Struct(self, struct dl_handle, dlhandle);
- if( ! dlhandle->open ){
- rb_raise(rb_eDLError, "closed handle");
- }
- handle = dlhandle->ptr;
-
- func = dlsym(handle, name);
- CHECK_DLERROR;
- if( !func ){
-#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__)
- {
- int len = strlen(name);
- char *name_a = (char*)xmalloc(len+2);
- strcpy(name_a, name);
- name_a[len] = 'A';
- name_a[len+1] = '\0';
- func = dlsym(handle, name_a);
- xfree(name_a);
- CHECK_DLERROR;
- if( !func ){
- for( i = 0; i < 256; i += 4 ){
- int len = strlen(name);
- char *name_n = (char*)xmalloc(len+5);
- sprintf(name_n, "%s@%d%c", name, i, 0);
- func = dlsym(handle, name_n);
- xfree(name_n);
- CHECK_DLERROR;
- if( func )
- {
- break;
- }
- }
- CHECK_DLERROR;
- if( !func ){
- rb_raise(rb_eDLError, "unknown symbol \"%s\"", name);
- }
- }
- }
-#else
- for( i = 0; i < 256; i += 4 ){
- int len = strlen(name);
- char *name_n = (char*)xmalloc(len+4);
- sprintf(name_n, "%s@%d", name, i);
- func = dlsym(handle, name_n);
- xfree(name_n);
- CHECK_DLERROR;
- if( func ){
- break;
- }
- }
- CHECK_DLERROR;
- if( !func ){
- rb_raise(rb_eDLError, "unknown symbol \"%s\"", name);
- }
-#endif
- }
-
- return PTR2NUM(func);
-}
-
-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, "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/trunk/ext/dl/lib/dl/callback.rb b/trunk/ext/dl/lib/dl/callback.rb
deleted file mode 100644
index d0b2c7a819..0000000000
--- a/trunk/ext/dl/lib/dl/callback.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require 'dl'
-require 'thread'
-
-module DL
- SEM = Mutex.new
-
- def set_callback_internal(proc_entry, addr_entry, argc, ty, &cbp)
- if( argc < 0 )
- raise(ArgumentError, "arity should not be less than 0.")
- end
- addr = nil
- SEM.synchronize{
- ary = proc_entry[ty]
- (0...MAX_CALLBACK).each{|n|
- idx = (n * DLSTACK_SIZE) + argc
- if( ary[idx].nil? )
- ary[idx] = cbp
- addr = addr_entry[ty][idx]
- break
- end
- }
- }
- addr
- end
-
- def set_cdecl_callback(ty, argc, &cbp)
- set_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, argc, ty, &cbp)
- end
-
- def set_stdcall_callback(ty, argc, &cbp)
- set_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, argc, ty, &cbp)
- end
-
- def remove_callback_internal(proc_entry, addr_entry, addr, ctype = nil)
- index = nil
- if( ctype )
- addr_entry[ctype].each_with_index{|xaddr, idx|
- if( xaddr == addr )
- index = idx
- end
- }
- else
- addr_entry.each{|ty,entry|
- entry.each_with_index{|xaddr, idx|
- if( xaddr == addr )
- index = idx
- end
- }
- }
- end
- if( proc_entry[ctype][index] )
- proc_entry[ctype][index] = nil
- return true
- else
- return false
- end
- end
-
- def remove_cdecl_callback(addr, ctype = nil)
- remove_callback_internal(CdeclCallbackProcs, CdeclCallbackAddrs, addr, ctype)
- end
-
- def remove_stdcall_callback(addr, ctype = nil)
- remove_callback_internal(StdcallCallbackProcs, StdcallCallbackAddrs, addr, ctype)
- end
-
- alias set_callback set_cdecl_callback
- alias remove_callback remove_cdecl_callback
-end
diff --git a/trunk/ext/dl/lib/dl/cparser.rb b/trunk/ext/dl/lib/dl/cparser.rb
deleted file mode 100644
index c897d1b69f..0000000000
--- a/trunk/ext/dl/lib/dl/cparser.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-module DL
- module CParser
- def parse_struct_signature(signature, tymap=nil)
- if( signature.is_a?(String) )
- signature = signature.split("\s*,\s*")
- end
- mems = []
- tys = []
- signature.each{|msig|
- tks = msig.split(/\s+(\*)?/)
- ty = tks[0..-2].join(" ")
- member = tks[-1]
-
- case ty
- when /\[(\d+)\]/
- n = $1.to_i
- ty.gsub!(/\s*\[\d+\]/,"")
- ty = [ty, n]
- when /\[\]/
- ty.gsub!(/\s*\[\]/, "*")
- end
-
- case member
- when /\[(\d+)\]/
- ty = [ty, $1.to_i]
- member.gsub!(/\s*\[\d+\]/,"")
- when /\[\]/
- ty = ty + "*"
- member.gsub!(/\s*\[\]/, "")
- end
-
- mems.push(member)
- tys.push(parse_ctype(ty,tymap))
- }
- return tys, mems
- end
-
- def parse_signature(signature, tymap=nil)
- tymap ||= {}
- signature = signature.gsub(/\s+/, " ").strip
- case signature
- 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, parse_ctype(ret, tymap), args.collect{|arg| parse_ctype(arg, tymap)}]
- else
- raise(RuntimeError,"can't parse the function prototype: #{proto}")
- end
- end
-
- def parse_ctype(ty, tymap=nil)
- tymap ||= {}
- case ty
- when Array
- return [parse_ctype(ty[0], tymap), ty[1]]
- when "void"
- return TYPE_VOID
- when "char"
- return TYPE_CHAR
- when "unsigned char"
- return -TYPE_CHAR
- when "short"
- return TYPE_SHORT
- when "unsigned short"
- return -TYPE_SHORT
- when "int"
- return TYPE_INT
- when "unsigned int"
- return -TYPE_INT
- when "long"
- return TYPE_LONG
- when "unsigned long"
- return -TYPE_LONG
- when "long long"
- if( defined?(TYPE_LONG_LONG) )
- return TYPE_LONG_LONG
- else
- raise(RuntimeError, "unsupported type: #{ty}")
- end
- when "unsigned long long"
- if( defined?(TYPE_LONG_LONG) )
- return -TYPE_LONG_LONG
- else
- raise(RuntimeError, "unsupported type: #{ty}")
- end
- when "float"
- return TYPE_FLOAT
- when "double"
- return TYPE_DOUBLE
- when /\*/, /\[\s*\]/
- return TYPE_VOIDP
- else
- if( tymap[ty] )
- return parse_ctype(tymap[ty], tymap)
- else
- raise(DLError, "unknown type: #{ty}")
- end
- end
- end
- end
-end
diff --git a/trunk/ext/dl/lib/dl/func.rb b/trunk/ext/dl/lib/dl/func.rb
deleted file mode 100644
index b29aebcc8b..0000000000
--- a/trunk/ext/dl/lib/dl/func.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-require 'dl'
-require 'dl/callback'
-require 'dl/stack'
-require 'dl/value'
-require 'thread'
-
-module DL
- class Function
- include DL
- include ValueUtil
-
- def initialize(cfunc, argtypes, &proc)
- @cfunc = cfunc
- @stack = Stack.new(argtypes.collect{|ty| ty.abs})
- if( @cfunc.ctype < 0 )
- @cfunc.ctype = @cfunc.ctype.abs
- @unsigned = true
- end
- if( proc )
- bind(&proc)
- end
- end
-
- def to_i()
- @cfunc.to_i
- end
-
- def call(*args, &block)
- funcs = []
- args = wrap_args(args, @stack.types, funcs, &block)
- r = @cfunc.call(@stack.pack(args))
- funcs.each{|f| f.unbind_at_call()}
- return wrap_result(r)
- end
-
- def wrap_result(r)
- case @cfunc.ctype
- when TYPE_VOIDP
- r = CPtr.new(r)
- else
- if( @unsigned )
- r = unsigned_value(r, @cfunc.ctype)
- end
- end
- r
- end
-
- def bind(&block)
- if( !block )
- raise(RuntimeError, "block must be given.")
- end
- if( @cfunc.ptr == 0 )
- cb = Proc.new{|*args|
- ary = @stack.unpack(args)
- @stack.types.each_with_index{|ty, idx|
- case ty
- when TYPE_VOIDP
- ary[idx] = CPtr.new(ary[idx])
- end
- }
- r = block.call(*ary)
- wrap_arg(r, @cfunc.ctype, [])
- }
- case @cfunc.calltype
- when :cdecl
- @cfunc.ptr = set_cdecl_callback(@cfunc.ctype, @stack.size, &cb)
- when :stdcall
- @cfunc.ptr = set_stdcall_callback(@cfunc.ctype, @stack.size, &cb)
- else
- raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
- end
- if( @cfunc.ptr == 0 )
- raise(RuntimeException, "can't bind C function.")
- end
- end
- end
-
- def unbind()
- if( @cfunc.ptr != 0 )
- case @cfunc.calltype
- when :cdecl
- remove_cdecl_callback(@cfunc.ptr, @cfunc.ctype)
- when :stdcall
- remove_stdcall_callback(@cfunc.ptr, @cfunc.ctype)
- else
- raise(RuntimeError, "unsupported calltype: #{@cfunc.calltype}")
- end
- @cfunc.ptr = 0
- end
- end
-
- def bind_at_call(&block)
- bind(&block)
- end
-
- def unbind_at_call()
- end
- end
-
- class TempFunction < Function
- def bind_at_call(&block)
- bind(&block)
- end
-
- def unbind_at_call()
- unbind()
- end
- end
-
- class CarriedFunction < Function
- def initialize(cfunc, argtypes, n)
- super(cfunc, argtypes)
- @carrier = []
- @index = n
- @mutex = Mutex.new
- end
-
- def create_carrier(data)
- ary = []
- userdata = [ary, data]
- @mutex.lock()
- @carrier.push(userdata)
- return dlwrap(userdata)
- end
-
- def bind_at_call(&block)
- userdata = @carrier[-1]
- userdata[0].push(block)
- bind{|*args|
- ptr = args[@index]
- if( !ptr )
- raise(RuntimeError, "The index of userdata should be lower than #{args.size}.")
- end
- userdata = dlunwrap(Integer(ptr))
- args[@index] = userdata[1]
- userdata[0][0].call(*args)
- }
- @mutex.unlock()
- end
- end
-end
diff --git a/trunk/ext/dl/lib/dl/import.rb b/trunk/ext/dl/lib/dl/import.rb
deleted file mode 100644
index f6fb35944d..0000000000
--- a/trunk/ext/dl/lib/dl/import.rb
+++ /dev/null
@@ -1,215 +0,0 @@
-require 'dl'
-require 'dl/func.rb'
-require 'dl/struct.rb'
-require 'dl/cparser.rb'
-
-module DL
- class CompositeHandler
- def initialize(handlers)
- @handlers = handlers
- end
-
- def handlers()
- @handlers
- end
-
- def sym(symbol)
- @handlers.each{|handle|
- if( handle )
- begin
- addr = handle.sym(symbol)
- return addr
- rescue DLError
- end
- end
- }
- return nil
- end
-
- def [](symbol)
- sym(symbol)
- end
- end
-
- module Importer
- include DL
- include CParser
- extend Importer
-
- def dlload(*libs)
- handles = libs.collect{|lib|
- case lib
- when nil
- nil
- when Handle
- lib
- when Importer
- lib.handlers
- else
- begin
- DL.dlopen(lib)
- rescue DLError
- raise(DLError, "can't load #{lib}")
- end
- end
- }.flatten()
- @handler = CompositeHandler.new(handles)
- @func_map = {}
- @type_alias = {}
- end
-
- def typealias(alias_type, orig_type)
- @type_alias[alias_type] = orig_type
- end
-
- def sizeof(ty)
- case ty
- when String
- ty = parse_ctype(ty, @type_alias).abs()
- case ty
- when TYPE_CHAR
- return SIZEOF_CHAR
- when TYPE_SHORT
- return SIZEOF_SHORT
- when TYPE_INT
- return SIZEOF_INT
- when TYPE_LONG
- return SIZEOF_LONG
- when TYPE_LONG_LONG
- return SIZEOF_LONG_LON
- when TYPE_FLOAT
- return SIZEOF_FLOAT
- when TYPE_DOUBLE
- return SIZEOF_DOUBLE
- when TYPE_VOIDP
- return SIZEOF_VOIDP
- else
- raise(DLError, "unknown type: #{ty}")
- end
- when Class
- if( ty.instance_methods().include?("to_ptr") )
- return ty.size()
- end
- end
- return CPtr[ty].size()
- end
-
- def parse_bind_options(opts)
- h = {}
- prekey = nil
- while( opt = opts.shift() )
- case opt
- when :stdcall, :cdecl
- h[:call_type] = opt
- when :carried, :temp, :temporal, :bind
- h[:callback_type] = opt
- h[:carrier] = opts.shift()
- else
- h[opt] = true
- end
- end
- h
- end
- private :parse_bind_options
-
- def extern(signature, *opts)
- symname, ctype, argtype = parse_signature(signature, @type_alias)
- opt = parse_bind_options(opts)
- f = import_function(symname, ctype, argtype, opt[:call_type])
- name = symname.gsub(/@.+/,'')
- @func_map[name] = f
- # define_method(name){|*args,&block| f.call(*args,&block)}
- module_eval(<<-EOS)
- def #{name}(*args, &block)
- @func_map['#{name}'].call(*args,&block)
- end
- EOS
- module_function(name)
- f
- end
-
- def bind(signature, *opts, &blk)
- name, ctype, argtype = parse_signature(signature, @type_alias)
- h = parse_bind_options(opts)
- case h[:callback_type]
- when :bind, nil
- f = bind_function(name, ctype, argtype, h[:call_type], &blk)
- when :temp, :temporal
- f = create_temp_function(name, ctype, argtype, h[:call_type])
- when :carried
- f = create_carried_function(name, ctype, argtype, h[:call_type], h[:carrier])
- else
- raise(RuntimeError, "unknown callback type: #{h[:callback_type]}")
- end
- @func_map[name] = f
- #define_method(name){|*args,&block| f.call(*args,&block)}
- module_eval(<<-EOS)
- def #{name}(*args,&block)
- @func_map['#{name}'].call(*args,&block)
- end
- EOS
- module_function(name)
- f
- end
-
- def struct(signature)
- tys, mems = parse_struct_signature(signature, @type_alias)
- DL::CStructBuilder.create(CStruct, tys, mems)
- end
-
- def union(signature)
- tys, mems = parse_struct_signature(signature, @type_alias)
- DL::CStructBuilder.create(CUnion, tys, mems)
- end
-
- def [](name)
- @func_map[name]
- end
-
- def create_value(ty, val=nil)
- s = struct([ty + " value"])
- ptr = s.malloc()
- if( val )
- ptr.value = val
- end
- return ptr
- end
- alias value create_value
-
- def import_value(ty, addr)
- s = struct([ty + " value"])
- ptr = s.new(addr)
- return ptr
- end
-
- def import_symbol(name)
- addr = @handler.sym(name)
- if( !addr )
- raise(DLError, "cannot find the symbol: #{name}")
- end
- CPtr.new(addr)
- end
-
- def import_function(name, ctype, argtype, call_type = nil)
- addr = @handler.sym(name)
- if( !addr )
- raise(DLError, "cannot find the function: #{name}()")
- end
- Function.new(CFunc.new(addr, ctype, name, call_type || :cdecl), argtype)
- end
-
- def bind_function(name, ctype, argtype, call_type = nil, &block)
- f = Function.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
- f.bind(&block)
- f
- end
-
- def create_temp_function(name, ctype, argtype, call_type = nil)
- TempFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
- end
-
- def create_carried_function(name, ctype, argtype, call_type = nil, n = 0)
- CarriedFunction.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype, n)
- end
- end
-end
diff --git a/trunk/ext/dl/lib/dl/pack.rb b/trunk/ext/dl/lib/dl/pack.rb
deleted file mode 100644
index ad91833b3a..0000000000
--- a/trunk/ext/dl/lib/dl/pack.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-require 'dl'
-
-module DL
- module PackInfo
- if( defined?(TYPE_LONG_LONG) )
- ALIGN_MAP = {
- TYPE_VOIDP => ALIGN_VOIDP,
- TYPE_CHAR => ALIGN_CHAR,
- TYPE_SHORT => ALIGN_SHORT,
- TYPE_INT => ALIGN_INT,
- TYPE_LONG => ALIGN_LONG,
- TYPE_LONG_LONG => ALIGN_LONG_LONG,
- TYPE_FLOAT => ALIGN_FLOAT,
- TYPE_DOUBLE => ALIGN_DOUBLE,
- -TYPE_CHAR => ALIGN_CHAR,
- -TYPE_SHORT => ALIGN_SHORT,
- -TYPE_INT => ALIGN_INT,
- -TYPE_LONG => ALIGN_LONG,
- -TYPE_LONG_LONG => ALIGN_LONG_LONG,
- }
-
- PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG) ? "q" : "l!"),
- TYPE_CHAR => "c",
- TYPE_SHORT => "s!",
- TYPE_INT => "i!",
- TYPE_LONG => "l!",
- TYPE_LONG_LONG => "q",
- TYPE_FLOAT => "f",
- TYPE_DOUBLE => "d",
- -TYPE_CHAR => "c",
- -TYPE_SHORT => "s!",
- -TYPE_INT => "i!",
- -TYPE_LONG => "l!",
- -TYPE_LONG_LONG => "q",
- }
-
- SIZE_MAP = {
- TYPE_VOIDP => SIZEOF_VOIDP,
- TYPE_CHAR => SIZEOF_CHAR,
- TYPE_SHORT => SIZEOF_SHORT,
- TYPE_INT => SIZEOF_INT,
- TYPE_LONG => SIZEOF_LONG,
- TYPE_LONG_LONG => SIZEOF_LONG_LONG,
- TYPE_FLOAT => SIZEOF_FLOAT,
- TYPE_DOUBLE => SIZEOF_DOUBLE,
- -TYPE_CHAR => SIZEOF_CHAR,
- -TYPE_SHORT => SIZEOF_SHORT,
- -TYPE_INT => SIZEOF_INT,
- -TYPE_LONG => SIZEOF_LONG,
- -TYPE_LONG_LONG => SIZEOF_LONG_LONG,
- }
- else
- ALIGN_MAP = {
- TYPE_VOIDP => ALIGN_VOIDP,
- TYPE_CHAR => ALIGN_CHAR,
- TYPE_SHORT => ALIGN_SHORT,
- TYPE_INT => ALIGN_INT,
- TYPE_LONG => ALIGN_LONG,
- TYPE_FLOAT => ALIGN_FLOAT,
- TYPE_DOUBLE => ALIGN_DOUBLE,
- -TYPE_CHAR => ALIGN_CHAR,
- -TYPE_SHORT => ALIGN_SHORT,
- -TYPE_INT => ALIGN_INT,
- -TYPE_LONG => ALIGN_LONG,
- }
-
- PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG) ? "q" : "l!"),
- TYPE_CHAR => "c",
- TYPE_SHORT => "s!",
- TYPE_INT => "i!",
- TYPE_LONG => "l!",
- TYPE_FLOAT => "f",
- TYPE_DOUBLE => "d",
- -TYPE_CHAR => "c",
- -TYPE_SHORT => "s!",
- -TYPE_INT => "i!",
- -TYPE_LONG => "l!",
- }
-
- SIZE_MAP = {
- TYPE_VOIDP => SIZEOF_VOIDP,
- TYPE_CHAR => SIZEOF_CHAR,
- TYPE_SHORT => SIZEOF_SHORT,
- TYPE_INT => SIZEOF_INT,
- TYPE_LONG => SIZEOF_LONG,
- TYPE_FLOAT => SIZEOF_FLOAT,
- TYPE_DOUBLE => SIZEOF_DOUBLE,
- -TYPE_CHAR => SIZEOF_CHAR,
- -TYPE_SHORT => SIZEOF_SHORT,
- -TYPE_INT => SIZEOF_INT,
- -TYPE_LONG => SIZEOF_LONG,
- }
- end
-
- def align(addr, align)
- d = addr % align
- if( d == 0 )
- addr
- else
- addr + (align - d)
- end
- end
- module_function :align
- end
-
- class Packer
- include PackInfo
-
- def Packer.[](*types)
- Packer.new(types)
- end
-
- def initialize(types)
- parse_types(types)
- end
-
- def size()
- @size
- end
-
- def pack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.pack(@template)
- when SIZEOF_LONG
- ary.pack(@template)
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- def unpack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.join().unpack(@template)
- when SIZEOF_LONG_LONG
- ary.join().unpack(@template)
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- private
-
- def parse_types(types)
- @template = ""
- addr = 0
- types.each{|t|
- orig_addr = addr
- if( t.is_a?(Array) )
- addr = align(orig_addr, ALIGN_MAP[TYPE_VOIDP])
- else
- addr = align(orig_addr, ALIGN_MAP[t])
- end
- d = addr - orig_addr
- if( d > 0 )
- @template << "x#{d}"
- end
- if( t.is_a?(Array) )
- @template << (PACK_MAP[t[0]] * t[1])
- addr += (SIZE_MAP[t[0]] * t[1])
- else
- @template << PACK_MAP[t]
- addr += SIZE_MAP[t]
- end
- }
- addr = align(addr, ALIGN_MAP[TYPE_VOIDP])
- @size = addr
- end
- end
-end
diff --git a/trunk/ext/dl/lib/dl/stack.rb b/trunk/ext/dl/lib/dl/stack.rb
deleted file mode 100644
index 9daf089775..0000000000
--- a/trunk/ext/dl/lib/dl/stack.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-require 'dl'
-
-module DL
- class Stack
- def Stack.[](*types)
- Stack.new(types)
- end
-
- def initialize(types)
- parse_types(types)
- end
-
- def size()
- @size
- end
-
- def types()
- @types
- end
-
- def pack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.pack(@template).unpack('l!*')
- when SIZEOF_LONG_LONG
- ary.pack(@template).unpack('q*')
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- def unpack(ary)
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- ary.pack('l!*').unpack(@template)
- when SIZEOF_LONG_LONG
- ary.pack('q*').unpack(@template)
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
-
- private
-
- def align(addr, align)
- d = addr % align
- if( d == 0 )
- addr
- else
- addr + (align - d)
- end
- end
-
-if( defined?(TYPE_LONG_LONG) )
- ALIGN_MAP = {
- TYPE_VOIDP => ALIGN_VOIDP,
- TYPE_CHAR => ALIGN_VOIDP,
- TYPE_SHORT => ALIGN_VOIDP,
- TYPE_INT => ALIGN_VOIDP,
- TYPE_LONG => ALIGN_VOIDP,
- TYPE_LONG_LONG => ALIGN_LONG_LONG,
- TYPE_FLOAT => ALIGN_FLOAT,
- TYPE_DOUBLE => ALIGN_DOUBLE,
- }
-
- PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG)? "q" : "l!"),
- TYPE_CHAR => "c",
- TYPE_SHORT => "s!",
- TYPE_INT => "i!",
- TYPE_LONG => "l!",
- TYPE_LONG_LONG => "q",
- TYPE_FLOAT => "f",
- TYPE_DOUBLE => "d",
- }
-
- SIZE_MAP = {
- TYPE_VOIDP => SIZEOF_VOIDP,
- TYPE_CHAR => SIZEOF_CHAR,
- TYPE_SHORT => SIZEOF_SHORT,
- TYPE_INT => SIZEOF_INT,
- TYPE_LONG => SIZEOF_LONG,
- TYPE_LONG_LONG => SIZEOF_LONG_LONG,
- TYPE_FLOAT => SIZEOF_FLOAT,
- TYPE_DOUBLE => SIZEOF_DOUBLE,
- }
-else
- ALIGN_MAP = {
- TYPE_VOIDP => ALIGN_VOIDP,
- TYPE_CHAR => ALIGN_VOIDP,
- TYPE_SHORT => ALIGN_VOIDP,
- TYPE_INT => ALIGN_VOIDP,
- TYPE_LONG => ALIGN_VOIDP,
- TYPE_FLOAT => ALIGN_FLOAT,
- TYPE_DOUBLE => ALIGN_DOUBLE,
- }
-
- PACK_MAP = {
- TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG)? "q" : "l!"),
- TYPE_CHAR => "c",
- TYPE_SHORT => "s!",
- TYPE_INT => "i!",
- TYPE_LONG => "l!",
- TYPE_FLOAT => "f",
- TYPE_DOUBLE => "d",
- }
-
- SIZE_MAP = {
- TYPE_VOIDP => SIZEOF_VOIDP,
- TYPE_CHAR => SIZEOF_CHAR,
- TYPE_SHORT => SIZEOF_SHORT,
- TYPE_INT => SIZEOF_INT,
- TYPE_LONG => SIZEOF_LONG,
- TYPE_FLOAT => SIZEOF_FLOAT,
- TYPE_DOUBLE => SIZEOF_DOUBLE,
- }
-end
-
- def parse_types(types)
- @types = types
- @template = ""
- addr = 0
- types.each{|t|
- orig_addr = addr
- addr = align(orig_addr, ALIGN_MAP[t])
- d = addr - orig_addr
- if( d > 0 )
- @template << "x#{d}"
- end
- @template << PACK_MAP[t]
- addr += SIZE_MAP[t]
- }
- if( addr % SIZEOF_VOIDP == 0 )
- @size = addr / SIZEOF_VOIDP
- else
- @size = (addr / SIZEOF_VOIDP) + 1
- end
- end
- end
-end
diff --git a/trunk/ext/dl/lib/dl/struct.rb b/trunk/ext/dl/lib/dl/struct.rb
deleted file mode 100644
index 4272b3960c..0000000000
--- a/trunk/ext/dl/lib/dl/struct.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-require 'dl'
-require 'dl/pack.rb'
-
-module DL
- class CStruct
- def CStruct.entity_class()
- CStructEntity
- end
- end
-
- class CUnion
- def CUnion.entity_class()
- CUnionEntity
- end
- end
-
- module CStructBuilder
- def create(klass, types, members)
- new_class = Class.new(klass){
- define_method(:initialize){|addr|
- @entity = klass.entity_class.new(addr, types)
- @entity.assign_names(members)
- }
- define_method(:to_ptr){ @entity }
- define_method(:to_i){ @entity.to_i }
- members.each{|name|
- define_method(name){ @entity[name] }
- define_method(name + "="){|val| @entity[name] = val }
- }
- }
- size = klass.entity_class.size(types)
- new_class.module_eval(<<-EOS)
- def new_class.size()
- #{size}
- end
- def new_class.malloc()
- addr = DL.malloc(#{size})
- new(addr)
- end
- EOS
- return new_class
- end
- module_function :create
- end
-
- class CStructEntity < CPtr
- include PackInfo
- include ValueUtil
-
- def CStructEntity.malloc(types, func = nil)
- addr = DL.malloc(CStructEntity.size(types))
- CStructEntity.new(addr, types, func)
- end
-
- def CStructEntity.size(types)
- offset = 0
- max_align = 0
- types.each_with_index{|t,i|
- orig_offset = offset
- if( t.is_a?(Array) )
- align = PackInfo::ALIGN_MAP[t[0]]
- offset = PackInfo.align(orig_offset, align)
- size = offset - orig_offset
- offset += (PackInfo::SIZE_MAP[t[0]] * t[1])
- else
- align = PackInfo::ALIGN_MAP[t]
- offset = PackInfo.align(orig_offset, align)
- size = offset - orig_offset
- offset += PackInfo::SIZE_MAP[t]
- end
- if (max_align < align)
- max_align = align
- end
- }
- offset = PackInfo.align(offset, max_align)
- offset
- end
-
- def initialize(addr, types, func = nil)
- set_ctypes(types)
- super(addr, @size, func)
- end
-
- def assign_names(members)
- @members = members
- end
-
- def set_ctypes(types)
- @ctypes = types
- @offset = []
- offset = 0
- max_align = 0
- types.each_with_index{|t,i|
- orig_offset = offset
- if( t.is_a?(Array) )
- align = ALIGN_MAP[t[0]]
- else
- align = ALIGN_MAP[t]
- end
- offset = PackInfo.align(orig_offset, align)
- size = offset - orig_offset
- @offset[i] = offset
- if( t.is_a?(Array) )
- offset += (SIZE_MAP[t[0]] * t[1])
- else
- offset += SIZE_MAP[t]
- end
- if (max_align < align)
- max_align = align
- end
- }
- offset = PackInfo.align(offset, max_align)
- @size = offset
- end
-
- def [](name)
- idx = @members.index(name)
- if( idx.nil? )
- raise(ArgumentError, "no such member: #{name}")
- end
- ty = @ctypes[idx]
- if( ty.is_a?(Array) )
- r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1])
- else
- r = super(@offset[idx], SIZE_MAP[ty.abs])
- end
- packer = Packer.new([ty])
- val = packer.unpack([r])
- case ty
- when Array
- case ty[0]
- when TYPE_VOIDP
- val = val.collect{|v| CPtr.new(v)}
- end
- when TYPE_VOIDP
- val = CPtr.new(val[0])
- else
- val = val[0]
- end
- if( ty.is_a?(Integer) && (ty < 0) )
- return unsigned_value(val, ty)
- elsif( ty.is_a?(Array) && (ty[0] < 0) )
- return val.collect{|v| unsigned_value(v,ty[0])}
- else
- return val
- end
- end
-
- def []=(name, val)
- idx = @members.index(name)
- if( idx.nil? )
- raise(ArgumentError, "no such member: #{name}")
- end
- ty = @ctypes[idx]
- packer = Packer.new([ty])
- val = wrap_arg(val, ty, [])
- buff = packer.pack([val].flatten())
- super(@offset[idx], buff.size, buff)
- if( ty.is_a?(Integer) && (ty < 0) )
- return unsigned_value(val, ty)
- elsif( ty.is_a?(Array) && (ty[0] < 0) )
- return val.collect{|v| unsigned_value(v,ty[0])}
- else
- return val
- end
- end
-
- def to_s()
- super(@size)
- end
- end
-
- class CUnionEntity < CStructEntity
- include PackInfo
-
- def CUnionEntity.malloc(types, func=nil)
- addr = DL.malloc(CUnionEntity.size(types))
- CUnionEntity.new(addr, types, func)
- end
-
- def CUnionEntity.size(types)
- size = 0
- types.each_with_index{|t,i|
- if( t.is_a?(Array) )
- tsize = PackInfo::SIZE_MAP[t[0]] * t[1]
- else
- tsize = PackInfo::SIZE_MAP[t]
- end
- if( tsize > size )
- size = tsize
- end
- }
- end
-
- def set_ctypes(types)
- @ctypes = types
- @offset = []
- @size = 0
- types.each_with_index{|t,i|
- @offset[i] = 0
- if( t.is_a?(Array) )
- size = SIZE_MAP[t[0]] * t[1]
- else
- size = SIZE_MAP[t]
- end
- if( size > @size )
- @size = size
- end
- }
- end
- end
-end
-
diff --git a/trunk/ext/dl/lib/dl/types.rb b/trunk/ext/dl/lib/dl/types.rb
deleted file mode 100644
index b85ac890cd..0000000000
--- a/trunk/ext/dl/lib/dl/types.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-module DL
- module Win32Types
- def included(m)
- m.module_eval{
- typealias "DWORD", "unsigned long"
- typealias "PDWORD", "unsigned long *"
- typealias "WORD", "unsigned short"
- typealias "PWORD", "unsigned short *"
- typealias "BOOL", "int"
- typealias "ATOM", "int"
- typealias "BYTE", "unsigned char"
- typealias "PBYTE", "unsigned char *"
- typealias "UINT", "unsigned int"
- typealias "ULONG", "unsigned long"
- typealias "UCHAR", "unsigned char"
- typealias "HANDLE", "unsigned long"
- typealias "PHANDLE", "void*"
- typealias "PVOID", "void*"
- typealias "LPCSTR", "char*"
- typealias "LPSTR", "char*"
- typealias "HINSTANCE", "unsigned int"
- typealias "HDC", "unsigned int"
- typealias "HWND", "unsigned int"
- }
- end
- module_function :included
- end
-
- module BasicTypes
- def included(m)
- m.module_eval{
- typealias "uint", "unsigned int"
- typealias "u_int", "unsigned int"
- typealias "ulong", "unsigned long"
- typealias "u_long", "unsigned long"
- }
- end
- module_function :included
- end
-end
diff --git a/trunk/ext/dl/lib/dl/value.rb b/trunk/ext/dl/lib/dl/value.rb
deleted file mode 100644
index aa7e0dd325..0000000000
--- a/trunk/ext/dl/lib/dl/value.rb
+++ /dev/null
@@ -1,108 +0,0 @@
-require 'dl'
-
-module DL
- module ValueUtil
- def unsigned_value(val, ty)
- case ty.abs
- when TYPE_CHAR
- [val].pack("c").unpack("C")[0]
- when TYPE_SHORT
- [val].pack("s!").unpack("S!")[0]
- when TYPE_INT
- [val].pack("i!").unpack("I!")[0]
- when TYPE_LONG
- [val].pack("l!").unpack("L!")[0]
- when TYPE_LONG_LONG
- [val].pack("q!").unpack("Q!")[0]
- else
- val
- end
- end
-
- def signed_value(val, ty)
- case ty.abs
- when TYPE_CHAR
- [val].pack("C").unpack("c")[0]
- when TYPE_SHORT
- [val].pack("S!").unpack("s!")[0]
- when TYPE_INT
- [val].pack("I!").unpack("i!")[0]
- when TYPE_LONG
- [val].pack("L!").unpack("l!")[0]
- when TYPE_LONG_LONG
- [val].pack("Q!").unpack("q!")[0]
- else
- val
- end
- end
-
- def wrap_args(args, tys, funcs, &block)
- result = []
- tys ||= []
- args.each_with_index{|arg, idx|
- result.push(wrap_arg(arg, tys[idx], funcs, &block))
- }
- result
- end
-
- def wrap_arg(arg, ty, funcs, &block)
- funcs ||= []
- case arg
- when CPtr
- return arg.to_i
- when IO
- case ty
- when TYPE_VOIDP
- return CPtr[arg].to_i
- else
- return arg.to_i
- end
- when Function
- if( block )
- arg.bind_at_call(&block)
- funcs.push(arg)
- end
- return arg.to_i
- when String
- if( ty.is_a?(Array) )
- return arg.unpack('C*')
- else
- case SIZEOF_VOIDP
- when SIZEOF_LONG
- return [arg].pack("p").unpack("l!")[0]
- when SIZEOF_LONG_LONG
- return [arg].pack("p").unpack("q")[0]
- else
- raise(RuntimeError, "sizeof(void*)?")
- end
- end
- when Float, Integer
- return arg
- when Array
- if( ty.is_a?(Array) ) # used only by struct
- case ty[0]
- when TYPE_VOIDP
- return arg.collect{|v| Integer(v)}
- when TYPE_CHAR
- if( arg.is_a?(String) )
- return val.unpack('C*')
- end
- end
- return arg
- else
- return arg
- end
- else
- if( arg.respond_to?(:to_ptr) )
- return arg.to_ptr.to_i
- else
- begin
- return Integer(arg)
- rescue
- raise(ArgumentError, "unknown argument type: #{arg.class}")
- end
- end
- end
- end
- end
-end
diff --git a/trunk/ext/dl/mkcallback.rb b/trunk/ext/dl/mkcallback.rb
deleted file mode 100644
index 21fb177f8b..0000000000
--- a/trunk/ext/dl/mkcallback.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-$out ||= $stdout
-$dl_h = ARGV[0] || "dl.h"
-
-# import DLSTACK_SIZE, DLSTACK_ARGS and so on
-File.open($dl_h){|f|
- pre = ""
- f.each{|line|
- line.chop!
- if( line[-1] == ?\ )
- line.chop!
- line.concat(" ")
- pre += line
- next
- end
- if( pre.size > 0 )
- line = pre + line
- pre = ""
- end
- case line
- when /#define\s+DLSTACK_SIZE\s+\(?(\d+)\)?/
- DLSTACK_SIZE = $1.to_i
- when /#define\s+DLSTACK_ARGS\s+(.+)/
- DLSTACK_ARGS = $1.to_i
- when /#define\s+DLTYPE_([A-Z_]+)\s+\(?(\d+)\)?/
- eval("#{$1} = #{$2}")
- when /#define\s+MAX_DLTYPE\s+\(?(\d+)\)?/
- MAX_DLTYPE = $1.to_i
- when /#define\s+MAX_CALLBACK\s+\(?(\d+)\)?/
- MAX_CALLBACK = $1.to_i
- end
- }
-}
-
-CDECL = "cdecl"
-STDCALL = "stdcall"
-
-CALLTYPES = [CDECL, STDCALL]
-
-DLTYPE = {
- VOID => {
- :name => 'void',
- :type => 'void',
- :conv => nil,
- },
- CHAR => {
- :name => 'char',
- :type => 'char',
- :conv => 'NUM2CHR(%s)'
- },
- SHORT => {
- :name => 'short',
- :type => 'short',
- :conv => 'NUM2INT(%s)',
- },
- INT => {
- :name => 'int',
- :type => 'int',
- :conv => 'NUM2INT(%s)',
- },
- LONG => {
- :name => 'long',
- :type => 'long',
- :conv => 'NUM2LONG(%s)',
- },
- LONG_LONG => {
- :name => 'long_long',
- :type => 'LONG_LONG',
- :conv => 'NUM2LL(%s)',
- },
- FLOAT => {
- :name => 'float',
- :type => 'float',
- :conv => 'RFLOAT_VALUE(%s)',
- },
- DOUBLE => {
- :name => 'double',
- :type => 'double',
- :conv => 'RFLOAT_VALUE(%s)',
- },
- VOIDP => {
- :name => 'ptr',
- :type => 'void *',
- :conv => 'NUM2PTR(%s)',
- },
-}
-
-
-def func_name(ty, argc, n, calltype)
- "rb_dl_callback_#{DLTYPE[ty][:name]}_#{argc}_#{n}_#{calltype}"
-end
-
-$out << (<<EOS)
-VALUE rb_DLCdeclCallbackAddrs, rb_DLCdeclCallbackProcs;
-VALUE rb_DLStdcallCallbackAddrs, rb_DLStdcallCallbackProcs;
-/*static void *cdecl_callbacks[MAX_DLTYPE][MAX_CALLBACK];*/
-/*static void *stdcall_callbacks[MAX_DLTYPE][MAX_CALLBACK];*/
-static ID cb_call;
-EOS
-
-for calltype in CALLTYPES
- case calltype
- when CDECL
- proc_entry = "rb_DLCdeclCallbackProcs"
- when STDCALL
- proc_entry = "rb_DLStdcallCallbackProcs"
- else
- raise "unknown calltype: #{calltype}"
- end
- for ty in 0..(MAX_DLTYPE-1)
- for argc in 0..(DLSTACK_SIZE-1)
- for n in 0..(MAX_CALLBACK-1)
- $out << (<<-EOS)
-
-static #{DLTYPE[ty][:type]}
-FUNC_#{calltype.upcase}(#{func_name(ty,argc,n,calltype)})(#{(0...argc).collect{|i| "DLSTACK_TYPE stack" + i.to_s}.join(", ")})
-{
- VALUE ret, cb#{argc > 0 ? ", args[#{argc}]" : ""};
-#{
- (0...argc).collect{|i|
- " args[%d] = LONG2NUM(stack%d);" % [i,i]
- }.join("\n")
-}
- cb = rb_ary_entry(rb_ary_entry(#{proc_entry}, #{ty}), #{(n * DLSTACK_SIZE) + argc});
- ret = rb_funcall2(cb, cb_call, #{argc}, #{argc > 0 ? 'args' : 'NULL'});
- return #{DLTYPE[ty][:conv] ? DLTYPE[ty][:conv] % "ret" : ""};
-}
-
- EOS
- end
- end
- end
-end
-
-$out << (<<EOS)
-static void
-rb_dl_init_callbacks()
-{
- cb_call = rb_intern("call");
-
- rb_DLCdeclCallbackProcs = rb_ary_new();
- rb_DLCdeclCallbackAddrs = rb_ary_new();
- rb_DLStdcallCallbackProcs = rb_ary_new();
- rb_DLStdcallCallbackAddrs = rb_ary_new();
- rb_define_const(rb_mDL, "CdeclCallbackProcs", rb_DLCdeclCallbackProcs);
- rb_define_const(rb_mDL, "CdeclCallbackAddrs", rb_DLCdeclCallbackAddrs);
- rb_define_const(rb_mDL, "StdcallCallbackProcs", rb_DLStdcallCallbackProcs);
- rb_define_const(rb_mDL, "StdcallCallbackAddrs", rb_DLStdcallCallbackAddrs);
-#{
- (0...MAX_DLTYPE).collect{|ty|
- sprintf(" rb_ary_push(rb_DLCdeclCallbackProcs, rb_ary_new3(%d,%s));",
- MAX_CALLBACK * DLSTACK_SIZE,
- (0...MAX_CALLBACK).collect{
- (0...DLSTACK_SIZE).collect{ "Qnil" }.join(",")
- }.join(","))
- }.join("\n")
-}
-#{
- (0...MAX_DLTYPE).collect{|ty|
- sprintf(" rb_ary_push(rb_DLCdeclCallbackAddrs, rb_ary_new3(%d,%s));",
- MAX_CALLBACK * DLSTACK_SIZE,
- (0...MAX_CALLBACK).collect{|i|
- (0...DLSTACK_SIZE).collect{|argc|
- "PTR2NUM(%s)" % func_name(ty,argc,i,CDECL)
- }.join(",")
- }.join(","))
- }.join("\n")
-}
-#{
- (0...MAX_DLTYPE).collect{|ty|
- sprintf(" rb_ary_push(rb_DLStdcallCallbackProcs, rb_ary_new3(%d,%s));",
- MAX_CALLBACK * DLSTACK_SIZE,
- (0...MAX_CALLBACK).collect{
- (0...DLSTACK_SIZE).collect{ "Qnil" }.join(",")
- }.join(","))
- }.join("\n")
-}
-#{
- (0...MAX_DLTYPE).collect{|ty|
- sprintf(" rb_ary_push(rb_DLStdcallCallbackAddrs, rb_ary_new3(%d,%s));",
- MAX_CALLBACK * DLSTACK_SIZE,
- (0...MAX_CALLBACK).collect{|i|
- (0...DLSTACK_SIZE).collect{|argc|
- "PTR2NUM(%s)" % func_name(ty,argc,i,STDCALL)
- }.join(",")
- }.join(","))
- }.join("\n")
-}
-}
-EOS
diff --git a/trunk/ext/dl/test/test_all.rb b/trunk/ext/dl/test/test_all.rb
deleted file mode 100644
index fb1f4939f9..0000000000
--- a/trunk/ext/dl/test/test_all.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require 'test_base'
-require 'dl/import'
-
-require 'test_dl2'
-require 'test_func'
-require 'test_import'
-
-case RUBY_PLATFORM
-when /cygwin/, /mingw32/, /mswin32/, /bccwin32/
- require 'test_win32'
-end
diff --git a/trunk/ext/dl/test/test_base.rb b/trunk/ext/dl/test/test_base.rb
deleted file mode 100644
index fc72db4e5e..0000000000
--- a/trunk/ext/dl/test/test_base.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require 'test/unit'
-require 'dl'
-
-case RUBY_PLATFORM
-when /cygwin/
- LIBC_SO = "cygwin1.dll"
- LIBM_SO = "cygwin1.dll"
-when /linux/
- LIBC_SO = "/lib/libc.so.6"
- LIBM_SO = "/lib/libm.so.6"
-when /mingw/, /mswin32/
- LIBC_SO = "msvcrt.dll"
- LIBM_SO = "msvcrt.dll"
-else
- LIBC_SO = ARGV[0]
- LIBM_SO = ARGV[1]
- if( !(LIBC_SO && LIBM_SO) )
- $stderr.puts("#{$0} <libc> <libm>")
- exit
- end
-end
-
-module DL
- class TestBase < Test::Unit::TestCase
- include Math
- include DL
-
- def setup
- @libc = dlopen(LIBC_SO)
- @libm = dlopen(LIBM_SO)
- end
-
- def assert_match(expected, actual, message="")
- assert(expected === actual, message)
- end
-
- def assert_positive(actual)
- assert(actual > 0)
- end
-
- def assert_zero(actual)
- assert(actual == 0)
- end
-
- def assert_negative(actual)
- assert(actual < 0)
- end
-
- def test_empty()
- end
- end
-end
diff --git a/trunk/ext/dl/test/test_dl2.rb b/trunk/ext/dl/test/test_dl2.rb
deleted file mode 100644
index 8c1f3e71b4..0000000000
--- a/trunk/ext/dl/test/test_dl2.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-require 'test_base.rb'
-require 'dl/callback'
-
-module DL
-class TestDL < TestBase
- def test_call_int()
- cfunc = CFunc.new(@libc['atoi'], TYPE_INT, 'atoi')
- x = cfunc.call(["100"].pack("p").unpack("l!*"))
- assert_equal(100, x)
-
- cfunc = CFunc.new(@libc['atoi'], TYPE_INT, 'atoi')
- x = cfunc.call(["-100"].pack("p").unpack("l!*"))
- assert_equal(-100, x)
- end
-
- def test_call_long()
- cfunc = CFunc.new(@libc['atol'], TYPE_LONG, 'atol')
- x = cfunc.call(["100"].pack("p").unpack("l!*"))
- assert_equal(100, x)
- cfunc = CFunc.new(@libc['atol'], TYPE_LONG, 'atol')
- x = cfunc.call(["-100"].pack("p").unpack("l!*"))
- assert_equal(-100, x)
- end
-
- def test_call_double()
- cfunc = CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof')
- x = cfunc.call(["0.1"].pack("p").unpack("l!*"))
- assert_match(0.09..0.11, x)
-
- cfunc = CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof')
- x = cfunc.call(["-0.1"].pack("p").unpack("l!*"))
- assert_match(-0.11 .. -0.09, x)
- end
-
- def test_sin()
- cfunc = CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin')
- x = cfunc.call([3.14/2].pack("d").unpack("l!*"))
- assert_equal(x, Math.sin(3.14/2))
-
- cfunc = CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin')
- x = cfunc.call([-3.14/2].pack("d").unpack("l!*"))
- assert_equal(Math.sin(-3.14/2), x)
- end
-
- def test_strlen()
- cfunc = CFunc.new(@libc['strlen'], TYPE_INT, 'strlen')
- x = cfunc.call(["abc"].pack("p").unpack("l!*"))
- assert_equal("abc".size, x)
- end
-
- def test_strcpy()
- buff = "xxxx"
- str = "abc"
- cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
- x = cfunc.call([buff,str].pack("pp").unpack("l!*"))
- assert_equal("abc\0", buff)
- assert_equal("abc\0", CPtr.new(x).to_s(4))
-
- buff = "xxxx"
- str = "abc"
- cfunc = CFunc.new(@libc['strncpy'], TYPE_VOIDP, 'strncpy')
- x = cfunc.call([buff,str,3].pack("ppi").unpack("l!*"))
- assert_equal("abcx", buff)
- assert_equal("abcx", CPtr.new(x).to_s(4))
-
- ptr = CPtr.malloc(4)
- str = "abc"
- cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
- x = cfunc.call([ptr.to_i,str].pack("lp").unpack("l!*"))
- assert_equal("abc\0", ptr[0,4])
- assert_equal("abc\0", CPtr.new(x).to_s(4))
- end
-
- def test_callback()
- buff = "foobarbaz"
- cb = set_callback(TYPE_INT,2){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
- cfunc = CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort')
- cfunc.call([buff, buff.size, 1, cb].pack("pI!I!L!").unpack("l!*"))
- assert_equal('aabbfoorz', buff)
- end
-
- def test_dlwrap()
- ary = [0,1,2,4,5]
- addr = dlwrap(ary)
- ary2 = dlunwrap(addr)
- assert_equal(ary, ary2)
- end
-
- def test_cptr()
- check = Proc.new{|str,ptr|
- assert_equal(str.size(), ptr.size())
- assert_equal(str, ptr.to_s())
- assert_equal(str[0,2], ptr.to_s(2))
- assert_equal(str[0,2], ptr[0,2])
- assert_equal(str[1,2], ptr[1,2])
- assert_equal(str[1,0], ptr[1,0])
- assert_equal(str[0].ord, ptr[0])
- assert_equal(str[1].ord, ptr[1])
- }
- str = 'abc'
- ptr = CPtr[str]
- check.call(str, ptr)
- str[0] = "c"
- ptr[0] = "c".ord
- check.call(str, ptr)
- str[0,2] = "aa"
- ptr[0,2] = "aa"
- check.call(str, ptr)
- end
-end
-end # module DL
diff --git a/trunk/ext/dl/test/test_func.rb b/trunk/ext/dl/test/test_func.rb
deleted file mode 100644
index 64a32d9565..0000000000
--- a/trunk/ext/dl/test/test_func.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'test_base'
-require 'dl/func'
-
-module DL
- class TestFunc < TestBase
- def test_strcpy()
- f = Function.new(CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy'),
- [TYPE_VOIDP, TYPE_VOIDP])
- buff = "000"
- str = f.call(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def test_isdigit()
- f = Function.new(CFunc.new(@libc['isdigit'], TYPE_INT, 'isdigit'),
- [TYPE_INT])
- r1 = f.call(?1)
- r2 = f.call(?2)
- rr = f.call(?r)
- assert_positive(r1)
- assert_positive(r2)
- assert_zero(rr)
- end
-
- def test_atof()
- f = Function.new(CFunc.new(@libc['atof'], TYPE_FLOAT, 'atof'),
- [TYPE_VOIDP])
- r = f.call("12.34")
- assert_match(12.00..13.00, r)
- end
-
- def test_strtod()
- f = Function.new(CFunc.new(@libc['strtod'], TYPE_DOUBLE, 'strtod'),
- [TYPE_VOIDP, TYPE_VOIDP])
- buff1 = "12.34"
- buff2 = " "
- r = f.call(buff1, buff2)
- assert_match(12.00..13.00, r)
- end
-
- def test_qsort1()
- cb = Function.new(CFunc.new(0, TYPE_INT, '<callback>qsort'),
- [TYPE_VOIDP, TYPE_VOIDP]){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
- qsort = Function.new(CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort'),
- [TYPE_VOIDP, TYPE_INT, TYPE_INT, TYPE_VOIDP])
- buff = "9341"
- qsort.call(buff, buff.size, 1, cb)
- assert_equal("1349", buff)
- end
-
- def test_qsort2()
- cb = TempFunction.new(CFunc.new(0, TYPE_INT, '<callback>qsort'),
- [TYPE_VOIDP, TYPE_VOIDP])
- qsort = Function.new(CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort'),
- [TYPE_VOIDP, TYPE_INT, TYPE_INT, TYPE_VOIDP])
- buff = "9341"
- qsort.call(buff, buff.size, 1, cb){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
- assert_equal("1349", buff)
- end
- end
-end
diff --git a/trunk/ext/dl/test/test_import.rb b/trunk/ext/dl/test/test_import.rb
deleted file mode 100644
index f0694637eb..0000000000
--- a/trunk/ext/dl/test/test_import.rb
+++ /dev/null
@@ -1,154 +0,0 @@
-require 'test_base'
-require 'dl/import'
-
-module DL
- module LIBC
- extend Importer
- dlload LIBC_SO, LIBM_SO
-
- typealias 'string', 'char*'
- typealias 'FILE*', 'void*'
-
- extern "void *strcpy(char*, char*)"
- extern "int isdigit(int)"
- extern "float atof(string)"
- extern "unsigned long strtoul(char*, char **, int)"
- extern "int qsort(void*, int, int, void*)"
- extern "void fprintf(FILE*, char*)"
- extern "int gettimeofday(timeval*, timezone*)" rescue nil
-
- QsortCallback = bind("void *qsort_callback(void*, void*)", :temp)
- BoundQsortCallback = bind("void *qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
- Timeval = struct [
- "long tv_sec",
- "long tv_usec",
- ]
- Timezone = struct [
- "int tz_minuteswest",
- "int tz_dsttime",
- ]
- MyStruct = struct [
- "short num[5]",
- "char c",
- "unsigned char buff[7]",
- ]
-
- CallCallback = bind("void call_callback(void*, void*)"){|ptr1, ptr2|
- f = Function.new(CFunc.new(ptr1.to_i, DL::TYPE_VOID, "<anonymous>"), [TYPE_VOIDP])
- f.call(ptr2)
- }
- CarriedFunction = bind("void callback_function(void*)", :carried, 0)
- end
-
- class TestImport < TestBase
- def test_malloc()
- s1 = LIBC::Timeval.malloc()
- s2 = LIBC::Timeval.malloc()
- assert_not_equal(s1.to_ptr.to_i, s2.to_ptr.to_i)
- end
-
- def test_sizeof()
- assert_equal(DL::SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
- assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
- end
-
- def test_unsigned_result()
- d = (2 ** 31) + 1
-
- r = LIBC.strtoul(d.to_s, 0, 0)
- assert_equal(d, r)
- end
-
- def test_io()
- if( RUBY_PLATFORM != DL::BUILD_RUBY_PLATFORM )
- return
- end
- io_in,io_out = IO.pipe()
- LIBC.fprintf(io_out, "hello")
- io_out.flush()
- io_out.close()
- str = io_in.read()
- io_in.close()
- assert_equal("hello", str)
- end
-
- def test_value()
- i = LIBC.value('int', 2)
- assert_equal(2, i.value)
-
- d = LIBC.value('double', 2.0)
- assert_equal(2.0, d.value)
-
- ary = LIBC.value('int[3]', [0,1,2])
- assert_equal([0,1,2], ary.value)
- end
-
- def test_carried_function()
- data1 = "data"
- data2 = nil
- LIBC.call_callback(LIBC::CarriedFunction, LIBC::CarriedFunction.create_carrier(data1)){|d|
- data2 = d
- }
- assert_equal(data1, data2)
- end
-
- def test_struct()
- s = LIBC::MyStruct.malloc()
- s.num = [0,1,2,3,4]
- s.c = ?a
- s.buff = "012345\377"
- assert_equal([0,1,2,3,4], s.num)
- assert_equal(?a, s.c)
- assert_equal([?0,?1,?2,?3,?4,?5,?\377], s.buff)
- end
-
- def test_gettimeofday()
- if( defined?(LIBC.gettimeofday) )
- timeval = LIBC::Timeval.malloc()
- timezone = LIBC::Timezone.malloc()
- LIBC.gettimeofday(timeval, timezone)
- cur = Time.now()
- assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
- end
- end
-
- def test_strcpy()
- buff = "000"
- str = LIBC.strcpy(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def test_isdigit()
- r1 = LIBC.isdigit(?1)
- r2 = LIBC.isdigit(?2)
- rr = LIBC.isdigit(?r)
- assert_positive(r1)
- assert_positive(r2)
- assert_zero(rr)
- end
-
- def test_atof()
- r = LIBC.atof("12.34")
- assert_match(12.00..13.00, r)
- end
-
- def test_strtod()
- f = Function.new(CFunc.new(@libc['strtod'], TYPE_DOUBLE, 'strtod'),
- [TYPE_VOIDP, TYPE_VOIDP])
- buff1 = "12.34"
- buff2 = " "
- r = f.call(buff1, buff2)
- assert_match(12.00..13.00, r)
- end
-
- def test_qsort()
- buff = "9341"
- LIBC.qsort(buff, buff.size, 1, LIBC::QsortCallback){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
- assert_equal("1349", buff)
- buff = "9341"
- LIBC.qsort(buff, buff.size, 1, LIBC::BoundQsortCallback)
- assert_equal("1349", buff)
- end
- end
-end
diff --git a/trunk/ext/dl/test/test_win32.rb b/trunk/ext/dl/test/test_win32.rb
deleted file mode 100644
index b2210287a1..0000000000
--- a/trunk/ext/dl/test/test_win32.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require 'test_base'
-require 'dl/import'
-require 'dl/types'
-
-module Win32API
- extend DL::Importer
-
- dlload "kernel32.dll"
-
- include DL::Win32Types
-
- OSVERSIONINFO = struct [
- "DWORD dwOSVersionInfoSize",
- "DWORD dwMajorVersion",
- "DWORD dwMinorVersion",
- "DWORD dwBuildNumber",
- "DWORD dwPlatformId",
- "UCHAR szCSDVersion[128]",
- ]
-
- typealias "POSVERSIONINFO", "OSVERSIONINFO*"
-
- extern "BOOL GetVersionEx(POSVERSIONINFO)", :stdcall
-
- def get_version_ex()
- ptr = OSVERSIONINFO.malloc()
- ptr.dwOSVersionInfoSize = OSVERSIONINFO.size
- ret = GetVersionEx(ptr)
- if( ret )
- ptr
- else
- nil
- end
- end
- module_function :get_version_ex
-end
-
-module DL
-class TestWin32 < TestBase
- def test_version()
- platform = Win32API.get_version_ex().dwPlatformId
- case ENV['OS']
- when 'Windows_NT'
- expect = 2
- when /Windows.+/
- expect = 1
- else
- expect = 0
- end
- assert_equal(expect, platform)
- end
-end
-end
diff --git a/trunk/ext/dl/win32/extconf.rb b/trunk/ext/dl/win32/extconf.rb
deleted file mode 100644
index a72ca49c06..0000000000
--- a/trunk/ext/dl/win32/extconf.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-if compiled?('dl') and $mswin||$bccwin||$mingw||$cygwin
- create_makefile('win32')
-end
diff --git a/trunk/ext/dl/win32/lib/Win32API.rb b/trunk/ext/dl/win32/lib/Win32API.rb
deleted file mode 100644
index b642e0c8fe..0000000000
--- a/trunk/ext/dl/win32/lib/Win32API.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- ruby -*-
-# for backward compatibility
-warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: Win32API is deprecated after Ruby 1.9.1; use dl directly instead" if $VERBOSE
-
-require 'dl'
-
-class Win32API
- DLL = {}
- TYPEMAP = {"0" => DL::TYPE_VOID, "S" => DL::TYPE_VOIDP, "I" => DL::TYPE_LONG}
-
- def initialize(dllname, func, import, export = "0")
- @proto = [import].join.tr("VPpNnLlIi", "0SSI").sub(/^(.)0*$/, '\1')
- handle = DLL[dllname] ||= DL.dlopen(dllname)
- @func = DL::CFunc.new(handle[func], TYPEMAP[export.tr("VPpNnLlIi", "0SSI")], func)
- end
-
- def call(*args)
- import = @proto.split("")
- args.each_with_index do |x, i|
- args[i], = [x == 0 ? nil : x].pack("p").unpack("l!*") if import[i] == "S"
- args[i], = [x].pack("I").unpack("i") if import[i] == "I"
- end
- ret, = @func.call(args)
- return ret || 0
- end
-
- alias Call call
-end
diff --git a/trunk/ext/dl/win32/lib/win32/registry.rb b/trunk/ext/dl/win32/lib/win32/registry.rb
deleted file mode 100644
index ccdd721818..0000000000
--- a/trunk/ext/dl/win32/lib/win32/registry.rb
+++ /dev/null
@@ -1,832 +0,0 @@
-=begin
-= Win32 Registry I/F
-win32/registry is registry accessor library for Win32 platform.
-It uses Win32API to call Win32 Registry APIs.
-
-== example
- Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\foo') do |reg|
- value = reg['foo'] # read a value
- value = reg['foo', Win32::Registry::REG_SZ] # read a value with type
- type, value = reg.read('foo') # read a value
- reg['foo'] = 'bar' # write a value
- reg['foo', Win32::Registry::REG_SZ] = 'bar' # write a value with type
- reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value
-
- reg.each_value { |name, type, data| ... } # Enumerate values
- reg.each_key { |key, wtime| ... } # Enumerate subkeys
-
- reg.delete_value(name) # Delete a value
- reg.delete_key(name) # Delete a subkey
- reg.delete_key(name, true) # Delete a subkey recursively
- end
-
-= Reference
-
-== Win32::Registry class
-
-=== including modules
-
-* Enumerable
-* Registry::Constants
-
-=== class methods
---- Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
---- Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |reg| ... }
- Open the registry key ((|subkey|)) under ((|key|)).
- ((|key|)) is Win32::Registry object of parent key.
- You can use predefined key HKEY_* (see ((<constants>)))
-
- ((|desired|)) and ((|opt|)) is access mask and key option.
- For detail, see ((<MSDN Library|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/regopenkeyex.asp>)).
-
- If block is given, the key is closed automatically.
-
---- Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
---- Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |reg| ... }
- Create or open the registry key ((|subkey|)) under ((|key|)).
- You can use predefined key HKEY_* (see ((<constants>)))
-
- If subkey is already exists, key is opened and Registry#((<created?>))
- method will return false.
-
- If block is given, the key is closed automatically.
-
---- Registry.expand_environ(str)
- Replace (({%\w+%})) into the environment value of ((|str|)).
- This method is used for REG_EXPAND_SZ.
-
- For detail, see ((<ExpandEnvironmentStrings|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp>)) Win32 API.
-
---- Registry.type2name(type)
- Convert registry type value to readable string.
-
---- Registry.wtime2time(wtime)
- Convert 64-bit FILETIME integer into Time object.
-
---- Registry.time2wtime(time)
- Convert Time object or Integer object into 64-bit FILETIME.
-
-=== instance methods
---- open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
- Same as (({Win32::((<Registry.open>))(self, subkey, desired, opt)}))
-
---- create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
- Same as (({Win32::((<Registry.create>))(self, subkey, desired, opt)}))
-
---- close
- Close key.
-
- After closed, most method raises error.
-
---- read(name, *rtype)
- Read a registry value named ((|name|)) and return array of
- [ ((|type|)), ((|data|)) ].
- When name is nil, the `default' value is read.
-
- ((|type|)) is value type. (see ((<Win32::Registry::Constants module>)))
- ((|data|)) is value data, its class is:
- :REG_SZ, REG_EXPAND_SZ
- String
- :REG_MULTI_SZ
- Array of String
- :REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD
- Integer
- :REG_BINARY
- String (contains binary data)
-
- When ((|rtype|)) is specified, the value type must be included by
- ((|rtype|)) array, or TypeError is raised.
-
---- self[name, *rtype]
- Read a registry value named ((|name|)) and return its value data.
- The class of value is same as ((<read>)) method returns.
-
- If the value type is REG_EXPAND_SZ, returns value data whose environment
- variables are replaced.
- If the value type is neither REG_SZ, REG_MULTI_SZ, REG_DWORD,
- REG_DWORD_BIG_ENDIAN, nor REG_QWORD, TypeError is raised.
-
- The meaning of ((|rtype|)) is same as ((<read>)) method.
-
---- read_s(name)
---- read_i(name)
---- read_bin(name)
- Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin)
- registry value named ((|name|)).
-
- If the values type does not match, TypeError is raised.
-
---- read_s_expand(name)
- Read a REG_SZ or REG_EXPAND_SZ registry value named ((|name|)).
-
- If the value type is REG_EXPAND_SZ, environment variables are replaced.
- Unless the value type is REG_SZ or REG_EXPAND_SZ, TypeError is raised.
-
---- write(name, type, data)
- Write ((|data|)) to a registry value named ((|name|)).
- When name is nil, write to the `default' value.
-
- ((|type|)) is type value. (see ((<Registry::Constants module>)))
- Class of ((|data|)) must be same as which ((<read>))
- method returns.
-
---- self[name, wtype = nil] = value
- Write ((|value|)) to a registry value named ((|name|)).
-
- If ((|wtype|)) is specified, the value type is it.
- Otherwise, the value type is depend on class of ((|value|)):
- :Integer
- REG_DWORD
- :String
- REG_SZ
- :Array
- REG_MULTI_SZ
-
---- write_s(name, value)
---- write_i(name, value)
---- write_bin(name, value)
- Write ((|value|)) to a registry value named ((|name|)).
-
- The value type is REG_SZ(write_s), REG_DWORD(write_i), or
- REG_BINARY(write_bin).
-
---- each { |name, type, value| ... }
---- each_value { |name, type, value| ... }
- Enumerate values.
-
---- each_key { |subkey, wtime| ... }
- Enumerate subkeys.
-
- ((|subkey|)) is String which contains name of subkey.
- ((|wtime|)) is last write time as FILETIME (64-bit integer).
- (see ((<Registry.wtime2time>)))
-
---- delete(name)
---- delete_value(name)
- Delete a registry value named ((|name|)).
- We can not delete the `default' value.
-
---- delete_key(name, recursive = false)
- Delete a subkey named ((|name|)) and all its values.
-
- If ((|recursive|)) is false, the subkey must not have subkeys.
- Otherwise, this method deletes all subkeys and values recursively.
-
---- flush
- Write all the attributes into the registry file.
-
---- created?
- Returns if key is created ((*newly*)).
- (see ((<Registry.create>)))
-
---- open?
- Returns if key is not closed.
-
---- hkey
- Returns key handle value.
-
---- parent
- Win32::Registry object of parent key, or nil if predefeined key.
-
---- keyname
- Same as ((|subkey|)) value of ((<Registry.open>)) or
- ((<Registry.create>)) method.
-
---- disposition
- Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY).
-
---- name
---- to_s
- Full path of key such as (({'HKEY_CURRENT_USER\SOFTWARE\foo\bar'})).
-
---- info
- Returns key information as Array of:
- :num_keys
- The number of subkeys.
- :max_key_length
- Maximum length of name of subkeys.
- :num_values
- The number of values.
- :max_value_name_length
- Maximum length of name of values.
- :max_value_length
- Maximum length of value of values.
- :descriptor_length
- Length of security descriptor.
- :wtime
- Last write time as FILETIME(64-bit integer)
-
- For detail, see ((<RegQueryInfoKey|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/regqueryinfokey.asp>)) Win32 API.
-
---- num_keys
---- max_key_length
---- num_values
---- max_value_name_length
---- max_value_length
---- descriptor_length
---- wtime
- Returns an item of key information.
-
-=== constants
---- HKEY_CLASSES_ROOT
---- HKEY_CURRENT_USER
---- HKEY_LOCAL_MACHINE
---- HKEY_PERFORMANCE_DATA
---- HKEY_CURRENT_CONFIG
---- HKEY_DYN_DATA
- Win32::Registry object whose key is predefined key.
- For detail, see ((<MSDN Library|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/predefined_keys.asp>)).
-
-== Win32::Registry::Constants module
-
-For detail, see ((<MSDN Library|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/registry.asp>)).
-
---- HKEY_*
- Predefined key ((*handle*)).
- These are Integer, not Win32::Registry.
-
---- REG_*
- Registry value type.
-
---- KEY_*
- Security access mask.
-
---- KEY_OPTIONS_*
- Key options.
-
---- REG_CREATED_NEW_KEY
---- REG_OPENED_EXISTING_KEY
- If the key is created newly or opened existing key.
- See also Registry#((<disposition>)) method.
-
-=end
-
-require 'Win32API'
-
-module Win32
- class Registry
- module Constants
- HKEY_CLASSES_ROOT = 0x80000000
- HKEY_CURRENT_USER = 0x80000001
- HKEY_LOCAL_MACHINE = 0x80000002
- HKEY_USERS = 0x80000003
- HKEY_PERFORMANCE_DATA = 0x80000004
- HKEY_PERFORMANCE_TEXT = 0x80000050
- HKEY_PERFORMANCE_NLSTEXT = 0x80000060
- HKEY_CURRENT_CONFIG = 0x80000005
- HKEY_DYN_DATA = 0x80000006
-
- REG_NONE = 0
- REG_SZ = 1
- REG_EXPAND_SZ = 2
- REG_BINARY = 3
- REG_DWORD = 4
- REG_DWORD_LITTLE_ENDIAN = 4
- REG_DWORD_BIG_ENDIAN = 5
- REG_LINK = 6
- REG_MULTI_SZ = 7
- REG_RESOURCE_LIST = 8
- REG_FULL_RESOURCE_DESCRIPTOR = 9
- REG_RESOURCE_REQUIREMENTS_LIST = 10
- REG_QWORD = 11
- REG_QWORD_LITTLE_ENDIAN = 11
-
- STANDARD_RIGHTS_READ = 0x00020000
- STANDARD_RIGHTS_WRITE = 0x00020000
- KEY_QUERY_VALUE = 0x0001
- KEY_SET_VALUE = 0x0002
- KEY_CREATE_SUB_KEY = 0x0004
- KEY_ENUMERATE_SUB_KEYS = 0x0008
- KEY_NOTIFY = 0x0010
- KEY_CREATE_LINK = 0x0020
- KEY_READ = STANDARD_RIGHTS_READ |
- KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY
- KEY_WRITE = STANDARD_RIGHTS_WRITE |
- KEY_SET_VALUE | KEY_CREATE_SUB_KEY
- KEY_EXECUTE = KEY_READ
- KEY_ALL_ACCESS = KEY_READ | KEY_WRITE | KEY_CREATE_LINK
-
- REG_OPTION_RESERVED = 0x0000
- REG_OPTION_NON_VOLATILE = 0x0000
- REG_OPTION_VOLATILE = 0x0001
- REG_OPTION_CREATE_LINK = 0x0002
- REG_OPTION_BACKUP_RESTORE = 0x0004
- REG_OPTION_OPEN_LINK = 0x0008
- REG_LEGAL_OPTION = REG_OPTION_RESERVED |
- REG_OPTION_NON_VOLATILE | REG_OPTION_CREATE_LINK |
- REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK
-
- REG_CREATED_NEW_KEY = 1
- REG_OPENED_EXISTING_KEY = 2
-
- REG_WHOLE_HIVE_VOLATILE = 0x0001
- REG_REFRESH_HIVE = 0x0002
- REG_NO_LAZY_FLUSH = 0x0004
- REG_FORCE_RESTORE = 0x0008
-
- MAX_KEY_LENGTH = 514
- MAX_VALUE_LENGTH = 32768
- end
- include Constants
- include Enumerable
-
- #
- # Error
- #
- class Error < ::StandardError
- FormatMessageA = Win32API.new('kernel32.dll', 'FormatMessageA', 'LPLLPLP', 'L')
- def initialize(code)
- @code = code
- msg = "\0".force_encoding(Encoding::ASCII_8BIT) * 1024
- len = FormatMessageA.call(0x1200, 0, code, 0, msg, 1024, 0)
- msg = msg[0, len].force_encoding(Encoding.find(Encoding.locale_charmap))
- super msg.tr("\r", '').chomp
- end
- attr_reader :code
- end
-
- #
- # Predefined Keys
- #
- class PredefinedKey < Registry
- def initialize(hkey, keyname)
- @hkey = hkey
- @parent = nil
- @keyname = keyname
- @disposition = REG_OPENED_EXISTING_KEY
- end
-
- # Predefined keys cannot be closed
- def close
- raise Error.new(5) ## ERROR_ACCESS_DENIED
- end
-
- # Fake class for Registry#open, Registry#create
- def class
- Registry
- end
-
- # Make all
- Constants.constants.grep(/^HKEY_/) do |c|
- Registry.const_set c, new(Constants.const_get(c), c)
- end
- end
-
- #
- # Win32 APIs
- #
- module API
- [
- %w/RegOpenKeyExA LPLLP L/,
- %w/RegCreateKeyExA LPLLLLPPP L/,
- %w/RegEnumValueA LLPPPPPP L/,
- %w/RegEnumKeyExA LLPPLLLP L/,
- %w/RegQueryValueExA LPLPPP L/,
- %w/RegSetValueExA LPLLPL L/,
- %w/RegDeleteValue LP L/,
- %w/RegDeleteKey LP L/,
- %w/RegFlushKey L L/,
- %w/RegCloseKey L L/,
- %w/RegQueryInfoKey LPPPPPPPPPPP L/,
- ].each do |fn|
- const_set fn[0].intern, Win32API.new('advapi32.dll', *fn)
- end
-
- module_function
-
- def check(result)
- raise Error, result, caller(2) if result != 0
- end
-
- def packdw(dw)
- [dw].pack('V')
- end
-
- def unpackdw(dw)
- dw += [0].pack('V')
- dw.unpack('V')[0]
- end
-
- def packqw(qw)
- [ qw & 0xFFFFFFFF, qw >> 32 ].pack('VV')
- end
-
- def unpackqw(qw)
- qw = qw.unpack('VV')
- (qw[1] << 32) | qw[0]
- end
-
- def OpenKey(hkey, name, opt, desired)
- result = packdw(0)
- check RegOpenKeyExA.call(hkey, name, opt, desired, result)
- unpackdw(result)
- end
-
- def CreateKey(hkey, name, opt, desired)
- result = packdw(0)
- disp = packdw(0)
- check RegCreateKeyExA.call(hkey, name, 0, 0, opt, desired,
- 0, result, disp)
- [ unpackdw(result), unpackdw(disp) ]
- end
-
- def EnumValue(hkey, index)
- name = ' ' * Constants::MAX_KEY_LENGTH
- size = packdw(Constants::MAX_KEY_LENGTH)
- check RegEnumValueA.call(hkey, index, name, size, 0, 0, 0, 0)
- name[0, unpackdw(size)]
- end
-
- def EnumKey(hkey, index)
- name = ' ' * Constants::MAX_KEY_LENGTH
- size = packdw(Constants::MAX_KEY_LENGTH)
- wtime = ' ' * 8
- check RegEnumKeyExA.call(hkey, index, name, size, 0, 0, 0, wtime)
- [ name[0, unpackdw(size)], unpackqw(wtime) ]
- end
-
- def QueryValue(hkey, name)
- type = packdw(0)
- size = packdw(0)
- check RegQueryValueExA.call(hkey, name, 0, type, 0, size)
- data = ' ' * unpackdw(size)
- check RegQueryValueExA.call(hkey, name, 0, type, data, size)
- [ unpackdw(type), data[0, unpackdw(size)] ]
- end
-
- def SetValue(hkey, name, type, data, size)
- check RegSetValueExA.call(hkey, name, 0, type, data, size)
- end
-
- def DeleteValue(hkey, name)
- check RegDeleteValue.call(hkey, name)
- end
-
- def DeleteKey(hkey, name)
- check RegDeleteKey.call(hkey, name)
- end
-
- def FlushKey(hkey)
- check RegFlushKey.call(hkey)
- end
-
- def CloseKey(hkey)
- check RegCloseKey.call(hkey)
- end
-
- def QueryInfoKey(hkey)
- subkeys = packdw(0)
- maxsubkeylen = packdw(0)
- values = packdw(0)
- maxvaluenamelen = packdw(0)
- maxvaluelen = packdw(0)
- secdescs = packdw(0)
- wtime = ' ' * 8
- check RegQueryInfoKey.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0,
- values, maxvaluenamelen, maxvaluelen, secdescs, wtime)
- [ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values),
- unpackdw(maxvaluenamelen), unpackdw(maxvaluelen),
- unpackdw(secdescs), unpackqw(wtime) ]
- end
- end
-
- #
- # utility functions
- #
- def self.expand_environ(str)
- str.gsub(/%([^%]+)%/) { ENV[$1] || ENV[$1.upcase] || $& }
- end
-
- @@type2name = { }
- %w[
- REG_NONE REG_SZ REG_EXPAND_SZ REG_BINARY REG_DWORD
- REG_DWORD_BIG_ENDIAN REG_LINK REG_MULTI_SZ
- REG_RESOURCE_LIST REG_FULL_RESOURCE_DESCRIPTOR
- REG_RESOURCE_REQUIREMENTS_LIST REG_QWORD
- ].each do |type|
- @@type2name[Constants.const_get(type)] = type
- end
-
- def self.type2name(type)
- @@type2name[type] || type.to_s
- end
-
- def self.wtime2time(wtime)
- Time.at((wtime - 116444736000000000) / 10000000)
- end
-
- def self.time2wtime(time)
- time.to_i * 10000000 + 116444736000000000
- end
-
- #
- # constructors
- #
- private_class_method :new
-
- def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
- subkey = subkey.chomp('\\')
- newkey = API.OpenKey(hkey.hkey, subkey, opt, desired)
- obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY)
- if block_given?
- begin
- yield obj
- ensure
- obj.close
- end
- else
- obj
- end
- end
-
- def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
- newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired)
- obj = new(newkey, hkey, subkey, disp)
- if block_given?
- begin
- yield obj
- ensure
- obj.close
- end
- else
- obj
- end
- end
-
- #
- # finalizer
- #
- @@final = proc { |hkey| proc { API.CloseKey(hkey[0]) if hkey[0] } }
-
- #
- # initialize
- #
- def initialize(hkey, parent, keyname, disposition)
- @hkey = hkey
- @parent = parent
- @keyname = keyname
- @disposition = disposition
- @hkeyfinal = [ hkey ]
- ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal)
- end
- attr_reader :hkey, :parent, :keyname, :disposition
-
- #
- # attributes
- #
- def created?
- @disposition == REG_CREATED_NEW_KEY
- end
-
- def open?
- !@hkey.nil?
- end
-
- def name
- parent = self
- name = @keyname
- while parent = parent.parent
- name = parent.keyname + '\\' + name
- end
- name
- end
-
- def inspect
- "\#<Win32::Registry key=#{name.inspect}>"
- end
-
- #
- # marshalling
- #
- def _dump(depth)
- raise TypeError, "can't dump Win32::Registry"
- end
-
- #
- # open/close
- #
- def open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk)
- self.class.open(self, subkey, desired, opt, &blk)
- end
-
- def create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk)
- self.class.create(self, subkey, desired, opt, &blk)
- end
-
- def close
- API.CloseKey(@hkey)
- @hkey = @parent = @keyname = nil
- @hkeyfinal[0] = nil
- end
-
- #
- # iterator
- #
- def each_value
- index = 0
- while true
- begin
- subkey = API.EnumValue(@hkey, index)
- rescue Error
- break
- end
- begin
- type, data = read(subkey)
- rescue Error
- next
- end
- yield subkey, type, data
- index += 1
- end
- index
- end
- alias each each_value
-
- def each_key
- index = 0
- while true
- begin
- subkey, wtime = API.EnumKey(@hkey, index)
- rescue Error
- break
- end
- yield subkey, wtime
- index += 1
- end
- index
- end
-
- def keys
- keys_ary = []
- each_key { |key,| keys_ary << key }
- keys_ary
- end
-
- #
- # reader
- #
- def read(name, *rtype)
- type, data = API.QueryValue(@hkey, name)
- unless rtype.empty? or rtype.include?(type)
- raise TypeError, "Type mismatch (expect #{rtype.inspect} but #{type} present)"
- end
- case type
- when REG_SZ, REG_EXPAND_SZ
- [ type, data.chop ]
- when REG_MULTI_SZ
- [ type, data.split(/\0/) ]
- when REG_BINARY
- [ type, data ]
- when REG_DWORD
- [ type, API.unpackdw(data) ]
- when REG_DWORD_BIG_ENDIAN
- [ type, data.unpack('N')[0] ]
- when REG_QWORD
- [ type, API.unpackqw(data) ]
- else
- raise TypeError, "Type #{type} is not supported."
- end
- end
-
- def [](name, *rtype)
- type, data = read(name, *rtype)
- case type
- when REG_SZ, REG_DWORD, REG_QWORD, REG_MULTI_SZ
- data
- when REG_EXPAND_SZ
- Registry.expand_environ(data)
- else
- raise TypeError, "Type #{type} is not supported."
- end
- end
-
- def read_s(name)
- read(name, REG_SZ)[1]
- end
-
- def read_s_expand(name)
- type, data = read(name, REG_SZ, REG_EXPAND_SZ)
- if type == REG_EXPAND_SZ
- Registry.expand_environ(data)
- else
- data
- end
- end
-
- def read_i(name)
- read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1]
- end
-
- def read_bin(name)
- read(name, REG_BINARY)[1]
- end
-
- #
- # writer
- #
- def write(name, type, data)
- case type
- when REG_SZ, REG_EXPAND_SZ
- data = data.to_s + "\0"
- when REG_MULTI_SZ
- data = data.to_a.join("\0") + "\0\0"
- when REG_BINARY
- data = data.to_s
- when REG_DWORD
- data = API.packdw(data.to_i)
- when REG_DWORD_BIG_ENDIAN
- data = [data.to_i].pack('N')
- when REG_QWORD
- data = API.packqw(data.to_i)
- else
- raise TypeError, "Unsupported type #{type}"
- end
- API.SetValue(@hkey, name, type, data, data.length)
- end
-
- def []=(name, rtype, value = nil)
- if value
- write name, rtype, value
- else
- case value = rtype
- when Integer
- write name, REG_DWORD, value
- when String
- write name, REG_SZ, value
- when Array
- write name, REG_MULTI_SZ, value
- else
- raise TypeError, "Unexpected type #{value.class}"
- end
- end
- value
- end
-
- def write_s(name, value)
- write name, REG_SZ, value.to_s
- end
-
- def write_i(name, value)
- write name, REG_DWORD, value.to_i
- end
-
- def write_bin(name, value)
- write name, REG_BINARY, value.to_s
- end
-
- #
- # delete
- #
- def delete_value(name)
- API.DeleteValue(@hkey, name)
- end
- alias delete delete_value
-
- def delete_key(name, recursive = false)
- if recursive
- open(name, KEY_ALL_ACCESS) do |reg|
- reg.keys.each do |key|
- begin
- reg.delete_key(key, true)
- rescue Error
- #
- end
- end
- end
- API.DeleteKey(@hkey, name)
- else
- begin
- API.EnumKey @hkey, 0
- rescue Error
- return API.DeleteKey(@hkey, name)
- end
- raise Error.new(5) ## ERROR_ACCESS_DENIED
- end
- end
-
- #
- # flush
- #
- def flush
- API.FlushKey @hkey
- end
-
- #
- # key information
- #
- def info
- API.QueryInfoKey(@hkey)
- end
- %w[
- num_keys max_key_length
- num_values max_value_name_length max_value_length
- descriptor_length wtime
- ].each_with_index do |s, i|
- eval <<-__END__
- def #{s}
- info[#{i}]
- end
- __END__
- end
- end
-end
diff --git a/trunk/ext/dl/win32/lib/win32/resolv.rb b/trunk/ext/dl/win32/lib/win32/resolv.rb
deleted file mode 100644
index 4e69f58085..0000000000
--- a/trunk/ext/dl/win32/lib/win32/resolv.rb
+++ /dev/null
@@ -1,370 +0,0 @@
-=begin
-= Win32 DNS and DHCP I/F
-
-=end
-
-require 'win32/registry'
-
-module Win32
- module Resolv
- API = Registry::API
-
- def self.get_hosts_path
- path = get_hosts_dir
- path = File.expand_path('hosts', path)
- File.exist?(path) ? path : nil
- end
-
- def self.get_resolv_info
- search, nameserver = get_info
- if search.empty?
- search = nil
- else
- search.delete("")
- search.uniq!
- end
- if nameserver.empty?
- nameserver = nil
- else
- nameserver.delete("")
- nameserver.delete("0.0.0.0")
- nameserver.uniq!
- end
- [ search, nameserver ]
- end
-
-getv = Win32API.new('kernel32.dll', 'GetVersionExA', 'P', 'L')
-info = [ 148, 0, 0, 0, 0 ].pack('V5') + "\0" * 128
-getv.call(info)
-if info.unpack('V5')[4] == 2 # VER_PLATFORM_WIN32_NT
-#====================================================================
-# Windows NT
-#====================================================================
- module_eval <<-'__EOS__', __FILE__, __LINE__+1
- TCPIP_NT = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters'
-
- class << self
- private
- def get_hosts_dir
- Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
- reg.read_s_expand('DataBasePath')
- end
- end
-
- def get_info
- search = nil
- nameserver = []
- Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|
- begin
- slist = reg.read_s('SearchList')
- search = slist.split(/,\s*/) unless slist.empty?
- rescue Registry::Error
- end
-
- if add_search = search.nil?
- search = []
- begin
- nvdom = reg.read_s('NV Domain')
- unless nvdom.empty?
- @search = [ nvdom ]
- if reg.read_i('UseDomainNameDevolution') != 0
- if /^[\w\d]+\./ =~ nvdom
- devo = $'
- end
- end
- end
- rescue Registry::Error
- end
- end
-
- reg.open('Interfaces') do |reg|
- reg.each_key do |iface,|
- reg.open(iface) do |regif|
- begin
- [ 'NameServer', 'DhcpNameServer' ].each do |key|
- begin
- ns = regif.read_s(key)
- rescue
- else
- unless ns.empty?
- nameserver.concat(ns.split(/[,\s]\s*/))
- break
- end
- end
- end
- rescue Registry::Error
- end
-
- if add_search
- begin
- [ 'Domain', 'DhcpDomain' ].each do |key|
- dom = regif.read_s(key)
- unless dom.empty?
- search.concat(dom.split(/,\s*/))
- break
- end
- end
- rescue Registry::Error
- end
- end
- end
- end
- end
- search << devo if add_search and devo
- end
- [ search.uniq, nameserver.uniq ]
- end
- end
- __EOS__
-else
-#====================================================================
-# Windows 9x
-#====================================================================
- module_eval <<-'__EOS__', __FILE__, __LINE__+1
- TCPIP_9X = 'SYSTEM\CurrentControlSet\Services\VxD\MSTCP'
- DHCP_9X = 'SYSTEM\CurrentControlSet\Services\VxD\DHCP'
- WINDOWS = 'Software\Microsoft\Windows\CurrentVersion'
-
- class << self
- # private
-
- def get_hosts_dir
- Registry::HKEY_LOCAL_MACHINE.open(WINDOWS) do |reg|
- reg.read_s_expand('SystemRoot')
- end
- end
-
- def get_info
- search = []
- nameserver = []
- begin
- Registry::HKEY_LOCAL_MACHINE.open(TCPIP_9X) do |reg|
- if reg.read_s("EnableDNS") == "1"
- domain = reg.read_s("Domain")
- ns = reg.read_s("NameServer")
- slist = reg.read_s("SearchList")
- search << domain unless domain.empty?
- search.concat(slist.split(/,\s*/))
- nameserver.concat(ns.split(/[,\s]\s*/))
- end
- end
- rescue Registry::Error
- end
-
- dhcpinfo = get_dhcpinfo
- search.concat(dhcpinfo[0])
- nameserver.concat(dhcpinfo[1])
- [ search, nameserver ]
- end
-
- def get_dhcpinfo
- macaddrs = {}
- ipaddrs = {}
- WsControl.get_iflist.each do |index, macaddr, *ipaddr|
- macaddrs[macaddr] = 1
- ipaddr.each { |ipaddr| ipaddrs[ipaddr] = 1 }
- end
- iflist = [ macaddrs, ipaddrs ]
-
- search = []
- nameserver = []
- version = -1
- Registry::HKEY_LOCAL_MACHINE.open(DHCP_9X) do |reg|
- begin
- version = API.unpackdw(reg.read_bin("Version"))
- rescue Registry::Error
- end
-
- reg.each_key do |key,|
- catch(:not_used) do
- reg.open(key) do |regdi|
- dom, ns = get_dhcpinfo_key(version, regdi, iflist)
- search << dom if dom
- nameserver.concat(ns) if ns
- end
- end
- end
- end
- [ search, nameserver ]
- end
-
- def get_dhcpinfo_95(reg)
- dhcp = reg.read_bin("DhcpInfo")
- [
- API.unpackdw(dhcp[4..7]),
- API.unpackdw(dhcp[8..11]),
- 1,
- dhcp[45..50],
- reg.read_bin("OptionInfo"),
- ]
- end
-
- def get_dhcpinfo_98(reg)
- [
- API.unpackdw(reg.read_bin("DhcpIPAddress")),
- API.unpackdw(reg.read_bin("DhcpSubnetMask")),
- API.unpackdw(reg.read_bin("HardwareType")),
- reg.read_bin("HardwareAddress"),
- reg.read_bin("OptionInfo"),
- ]
- end
-
- def get_dhcpinfo_key(version, reg, iflist)
- info = case version
- when 1
- get_dhcpinfo_95(reg)
- when 2
- get_dhcpinfo_98(reg)
- else
- begin
- get_dhcpinfo_98(reg)
- rescue Registry::Error
- get_dhcpinfo_95(reg)
- end
- end
- ipaddr, netmask, hwtype, macaddr, opt = info
- throw :not_used unless
- ipaddr and ipaddr != 0 and
- netmask and netmask != 0 and
- macaddr and macaddr.size == 6 and
- hwtype == 1 and
- iflist[0][macaddr] and iflist[1][ipaddr]
-
- size = opt.size
- idx = 0
- while idx <= size
- opttype = opt[idx]
- optsize = opt[idx + 1]
- optval = opt[idx + 2, optsize]
- case opttype
- when 0xFF ## term
- break
- when 0x0F ## domain
- domain = optval.chomp("\0")
- when 0x06 ## dns
- nameserver = optval.scan(/..../).collect { |addr|
- "%d.%d.%d.%d" % addr.unpack('C4')
- }
- end
- idx += optsize + 2
- end
- [ domain, nameserver ]
- rescue Registry::Error
- throw :not_used
- end
- end
-
- module WsControl
- WsControl = Win32API.new('wsock32.dll', 'WsControl', 'LLPPPP', 'L')
- WSAGetLastError = Win32API.new('wsock32.dll', 'WSAGetLastError', 'V', 'L')
-
- MAX_TDI_ENTITIES = 512
- IPPROTO_TCP = 6
- WSCTL_TCP_QUERY_INFORMATION = 0
- INFO_CLASS_GENERIC = 0x100
- INFO_CLASS_PROTOCOL = 0x200
- INFO_TYPE_PROVIDER = 0x100
- ENTITY_LIST_ID = 0
- GENERIC_ENTITY = 0
- CL_NL_ENTITY = 0x301
- IF_ENTITY = 0x200
- ENTITY_TYPE_ID = 1
- CL_NL_IP = 0x303
- IF_MIB = 0x202
- IF_MIB_STATS_ID = 1
- IP_MIB_ADDRTABLE_ENTRY_ID = 0x102
-
- def self.wsctl(tei_entity, tei_instance,
- toi_class, toi_type, toi_id,
- buffsize)
- reqinfo = [
- ## TDIEntityID
- tei_entity, tei_instance,
- ## TDIObjectID
- toi_class, toi_type, toi_id,
- ## TCP_REQUEST_INFORMATION_EX
- ""
- ].pack('VVVVVa16')
- reqsize = API.packdw(reqinfo.size)
- buff = "\0" * buffsize
- buffsize = API.packdw(buffsize)
- result = WsControl.call(
- IPPROTO_TCP,
- WSCTL_TCP_QUERY_INFORMATION,
- reqinfo, reqsize,
- buff, buffsize)
- if result != 0
- raise RuntimeError, "WsControl failed.(#{result})"
- end
- [ buff, API.unpackdw(buffsize) ]
- end
- private_class_method :wsctl
-
- def self.get_iflist
- # Get TDI Entity List
- entities, size =
- wsctl(GENERIC_ENTITY, 0,
- INFO_CLASS_GENERIC,
- INFO_TYPE_PROVIDER,
- ENTITY_LIST_ID,
- MAX_TDI_ENTITIES * 8) # sizeof(TDIEntityID)
- entities = entities[0, size].
- scan(/.{8}/).
- collect { |e| e.unpack('VV') }
-
- # Get MIB Interface List
- iflist = []
- ifcount = 0
- entities.each do |entity, instance|
- if( (entity & IF_ENTITY)>0 )
- ifcount += 1
- etype, = wsctl(entity, instance,
- INFO_CLASS_GENERIC,
- INFO_TYPE_PROVIDER,
- ENTITY_TYPE_ID,
- 4)
- if( (API.unpackdw(etype) & IF_MIB)==IF_MIB )
- ifentry, = wsctl(entity, instance,
- INFO_CLASS_PROTOCOL,
- INFO_TYPE_PROVIDER,
- IF_MIB_STATS_ID,
- 21 * 4 + 8 + 130) # sizeof(IFEntry)
- iflist << [
- API.unpackdw(ifentry[0,4]),
- ifentry[20, 6]
- ]
- end
- end
- end
-
- # Get IP Addresses
- entities.each do |entity, instance|
- if entity == CL_NL_ENTITY
- etype, = wsctl(entity, instance,
- INFO_CLASS_GENERIC,
- INFO_TYPE_PROVIDER,
- ENTITY_TYPE_ID,
- 4)
- if API.unpackdw(etype) == CL_NL_IP
- ipentries, = wsctl(entity, instance,
- INFO_CLASS_PROTOCOL,
- INFO_TYPE_PROVIDER,
- IP_MIB_ADDRTABLE_ENTRY_ID,
- 24 * (ifcount+1)) # sizeof(IPAddrEntry)
- ipentries.scan(/.{24}/) do |ipentry|
- ipaddr, index = ipentry.unpack('VV')
- if ifitem = iflist.assoc(index)
- ifitem << ipaddr
- end
- end
- end
- end
- end
- iflist
- end
- end
- __EOS__
-end
-#====================================================================
- end
-end
diff --git a/trunk/ext/dl/win32/lib/win32/sspi.rb b/trunk/ext/dl/win32/lib/win32/sspi.rb
deleted file mode 100644
index ef90ae35a7..0000000000
--- a/trunk/ext/dl/win32/lib/win32/sspi.rb
+++ /dev/null
@@ -1,330 +0,0 @@
-#
-# = win32/sspi.rb
-#
-# Copyright (c) 2006-2007 Justin Bailey
-#
-# Written and maintained by Justin Bailey <jgbailey@gmail.com>.
-#
-# This program is free software. You can re-distribute and/or
-# modify this program under the same terms of ruby itself ---
-# Ruby Distribution License or GNU General Public License.
-#
-
-require 'Win32API'
-
-# Implements bindings to Win32 SSPI functions, focused on authentication to a proxy server over HTTP.
-module Win32
- module SSPI
- # Specifies how credential structure requested will be used. Only SECPKG_CRED_OUTBOUND is used
- # here.
- SECPKG_CRED_INBOUND = 0x00000001
- SECPKG_CRED_OUTBOUND = 0x00000002
- SECPKG_CRED_BOTH = 0x00000003
-
- # Format of token. NETWORK format is used here.
- SECURITY_NATIVE_DREP = 0x00000010
- SECURITY_NETWORK_DREP = 0x00000000
-
- # InitializeSecurityContext Requirement flags
- ISC_REQ_REPLAY_DETECT = 0x00000004
- ISC_REQ_SEQUENCE_DETECT = 0x00000008
- ISC_REQ_CONFIDENTIALITY = 0x00000010
- ISC_REQ_USE_SESSION_KEY = 0x00000020
- ISC_REQ_PROMPT_FOR_CREDS = 0x00000040
- ISC_REQ_CONNECTION = 0x00000800
-
- # Win32 API Functions. Uses Win32API to bind methods to constants contained in class.
- module API
- # Can be called with AcquireCredentialsHandle.call()
- AcquireCredentialsHandle = Win32API.new("secur32", "AcquireCredentialsHandle", 'ppLpppppp', 'L')
- # Can be called with InitializeSecurityContext.call()
- InitializeSecurityContext = Win32API.new("secur32", "InitializeSecurityContext", 'pppLLLpLpppp', 'L')
- # Can be called with DeleteSecurityContext.call()
- DeleteSecurityContext = Win32API.new("secur32", "DeleteSecurityContext", 'P', 'L')
- # Can be called with FreeCredentialsHandle.call()
- FreeCredentialsHandle = Win32API.new("secur32", "FreeCredentialsHandle", 'P', 'L')
- end
-
- # SecHandle struct
- class SecurityHandle
- def upper
- @struct.unpack("LL")[1]
- end
-
- def lower
- @struct.unpack("LL")[0]
- end
-
- def to_p
- @struct ||= "\0" * 8
- end
- end
-
- # Some familiar aliases for the SecHandle structure
- CredHandle = CtxtHandle = SecurityHandle
-
- # TimeStamp struct
- class TimeStamp
- attr_reader :struct
-
- def to_p
- @struct ||= "\0" * 8
- end
- end
-
- # Creates binary representaiton of a SecBufferDesc structure,
- # including the SecBuffer contained inside.
- class SecurityBuffer
-
- SECBUFFER_TOKEN = 2 # Security token
-
- TOKENBUFSIZE = 12288
- SECBUFFER_VERSION = 0
-
- def initialize(buffer = nil)
- @buffer = buffer || "\0" * TOKENBUFSIZE
- @bufferSize = @buffer.length
- @type = SECBUFFER_TOKEN
- end
-
- def bufferSize
- unpack
- @bufferSize
- end
-
- def bufferType
- unpack
- @type
- end
-
- def token
- unpack
- @buffer
- end
-
- def to_p
- # Assumption is that when to_p is called we are going to get a packed structure. Therefore,
- # set @unpacked back to nil so we know to unpack when accessors are next accessed.
- @unpacked = nil
- # Assignment of inner structure to variable is very important here. Without it,
- # will not be able to unpack changes to the structure. Alternative, nested unpacks,
- # does not work (i.e. @struct.unpack("LLP12")[2].unpack("LLP12") results in "no associated pointer")
- @sec_buffer ||= [@bufferSize, @type, @buffer].pack("LLP")
- @struct ||= [SECBUFFER_VERSION, 1, @sec_buffer].pack("LLP")
- end
-
- private
-
- # Unpacks the SecurityBufferDesc structure into member variables. We
- # only want to do this once per struct, so the struct is deleted
- # after unpacking.
- def unpack
- if ! @unpacked && @sec_buffer && @struct
- @bufferSize, @type = @sec_buffer.unpack("LL")
- @buffer = @sec_buffer.unpack("LLP#{@bufferSize}")[2]
- @struct = nil
- @sec_buffer = nil
- @unpacked = true
- end
- end
- end
-
- # SEC_WINNT_AUTH_IDENTITY structure
- class Identity
- SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1
-
- attr_accessor :user, :domain, :password
-
- def initialize(user = nil, domain = nil, password = nil)
- @user = user
- @domain = domain
- @password = password
- @flags = SEC_WINNT_AUTH_IDENTITY_ANSI
- end
-
- def to_p
- [@user, @user ? @user.length : 0,
- @domain, @domain ? @domain.length : 0,
- @password, @password ? @password.length : 0,
- @flags].pack("PLPLPLL")
- end
- end
-
- # Takes a return result from an SSPI function and interprets the value.
- class SSPIResult
- # Good results
- SEC_E_OK = 0x00000000
- SEC_I_CONTINUE_NEEDED = 0x00090312
-
- # These are generally returned by InitializeSecurityContext
- SEC_E_INSUFFICIENT_MEMORY = 0x80090300
- SEC_E_INTERNAL_ERROR = 0x80090304
- SEC_E_INVALID_HANDLE = 0x80090301
- SEC_E_INVALID_TOKEN = 0x80090308
- SEC_E_LOGON_DENIED = 0x8009030C
- SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311
- SEC_E_NO_CREDENTIALS = 0x8009030E
- SEC_E_TARGET_UNKNOWN = 0x80090303
- SEC_E_UNSUPPORTED_FUNCTION = 0x80090302
- SEC_E_WRONG_PRINCIPAL = 0x80090322
-
- # These are generally returned by AcquireCredentialsHandle
- SEC_E_NOT_OWNER = 0x80090306
- SEC_E_SECPKG_NOT_FOUND = 0x80090305
- SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D
-
- @@map = {}
- constants.each { |v| @@map[self.const_get(v.to_s)] = v }
-
- attr_reader :value
-
- def initialize(value)
- # convert to unsigned long
- value = [value].pack("L").unpack("L").first
- raise "#{value.to_s(16)} is not a recognized result" unless @@map.has_key? value
- @value = value
- end
-
- def to_s
- @@map[@value].to_s
- end
-
- def ok?
- @value == SEC_I_CONTINUE_NEEDED || @value == SEC_E_OK
- end
-
- def ==(other)
- if other.is_a?(SSPIResult)
- @value == other.value
- elsif other.is_a?(Fixnum)
- @value == @@map[other]
- else
- false
- end
- end
- end
-
- # Handles "Negotiate" type authentication. Geared towards authenticating with a proxy server over HTTP
- class NegotiateAuth
- attr_accessor :credentials, :context, :contextAttributes, :user, :domain
-
- # Default request flags for SSPI functions
- REQUEST_FLAGS = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION
-
- # NTLM tokens start with this header always. Encoding alone adds "==" and newline, so remove those
- B64_TOKEN_PREFIX = ["NTLMSSP"].pack("m").delete("=\n")
-
- # Given a connection and a request path, performs authentication as the current user and returns
- # the response from a GET request. The connnection should be a Net::HTTP object, and it should
- # have been constructed using the Net::HTTP.Proxy method, but anything that responds to "get" will work.
- # If a user and domain are given, will authenticate as the given user.
- # Returns the response received from the get method (usually Net::HTTPResponse)
- def NegotiateAuth.proxy_auth_get(http, path, user = nil, domain = nil)
- raise "http must respond to :get" unless http.respond_to?(:get)
- nego_auth = self.new user, domain
-
- resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.get_initial_token }
- if resp["Proxy-Authenticate"]
- resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.complete_authentication(resp["Proxy-Authenticate"].split(" ").last.strip) }
- end
-
- resp
- end
-
- # Creates a new instance ready for authentication as the given user in the given domain.
- # Defaults to current user and domain as defined by ENV["USERDOMAIN"] and ENV["USERNAME"] if
- # no arguments are supplied.
- def initialize(user = nil, domain = nil)
- if user.nil? && domain.nil? && ENV["USERNAME"].nil? && ENV["USERDOMAIN"].nil?
- raise "A username or domain must be supplied since they cannot be retrieved from the environment"
- end
-
- @user = user || ENV["USERNAME"]
- @domain = domain || ENV["USERDOMAIN"]
- end
-
- # Gets the initial Negotiate token. Returns it as a base64 encoded string suitable for use in HTTP. Can
- # be easily decoded, however.
- def get_initial_token
- raise "This object is no longer usable because its resources have been freed." if @cleaned_up
- get_credentials
-
- outputBuffer = SecurityBuffer.new
- @context = CtxtHandle.new
- @contextAttributes = "\0" * 4
-
- result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, nil, nil,
- REQUEST_FLAGS,0, SECURITY_NETWORK_DREP, nil, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))
-
- if result.ok? then
- return encode_token(outputBuffer.token)
- else
- raise "Error: #{result.to_s}"
- end
- end
-
- # Takes a token and gets the next token in the Negotiate authentication chain. Token can be Base64 encoded or not.
- # The token can include the "Negotiate" header and it will be stripped.
- # Does not indicate if SEC_I_CONTINUE or SEC_E_OK was returned.
- # Token returned is Base64 encoded w/ all new lines removed.
- def complete_authentication(token)
- raise "This object is no longer usable because its resources have been freed." if @cleaned_up
-
- # Nil token OK, just set it to empty string
- token = "" if token.nil?
-
- if token.include? "Negotiate"
- # If the Negotiate prefix is passed in, assume we are seeing "Negotiate <token>" and get the token.
- token = token.split(" ").last
- end
-
- if token.include? B64_TOKEN_PREFIX
- # indicates base64 encoded token
- token = token.strip.unpack("m")[0]
- end
-
- outputBuffer = SecurityBuffer.new
- result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, @context.to_p, nil,
- REQUEST_FLAGS, 0, SECURITY_NETWORK_DREP, SecurityBuffer.new(token).to_p, 0,
- @context.to_p,
- outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p))
-
- if result.ok? then
- return encode_token(outputBuffer.token)
- else
- raise "Error: #{result.to_s}"
- end
- ensure
- # need to make sure we don't clean up if we've already cleaned up.
- clean_up unless @cleaned_up
- end
-
- private
-
- def clean_up
- # free structures allocated
- @cleaned_up = true
- API::FreeCredentialsHandle.call(@credentials.to_p)
- API::DeleteSecurityContext.call(@context.to_p)
- @context = nil
- @credentials = nil
- @contextAttributes = nil
- end
-
- # Gets credentials based on user, domain or both. If both are nil, an error occurs
- def get_credentials
- @credentials = CredHandle.new
- ts = TimeStamp.new
- @identity = Identity.new @user, @domain
- result = SSPIResult.new(API::AcquireCredentialsHandle.call(nil, "Negotiate", SECPKG_CRED_OUTBOUND, nil, @identity.to_p,
- nil, nil, @credentials.to_p, ts.to_p))
- raise "Error acquire credentials: #{result}" unless result.ok?
- end
-
- def encode_token(t)
- # encode64 will add newlines every 60 characters so we need to remove those.
- [t].pack("m").delete("\n")
- end
- end
- end
-end \ No newline at end of file