diff --git a/ext/tcl_ruby/compat.h b/ext/tcl_ruby/compat.h new file mode 100644 index 0000000..033f348 --- /dev/null +++ b/ext/tcl_ruby/compat.h @@ -0,0 +1,57 @@ +/* contains basic macros to facilitate ruby 1.8 and ruby 1.9 compatibility */ + +#ifndef GUARD_COMPAT_H +#define GUARD_COMPAT_H + +#include + +/* test for 1.9 */ +#if !defined(RUBY_19) && defined(ROBJECT_EMBED_LEN_MAX) +# define RUBY_19 +#endif + +/* macros for backwards compatibility with 1.8 */ +#ifndef RUBY_19 +# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl) +# define RCLASS_SUPER(c) (RCLASS(c)->super) +# define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl) +# define OBJ_UNTRUSTED OBJ_TAINTED +# include "st.h" +#endif + +#ifdef RUBY_19 +inline static VALUE +class_alloc(VALUE flags, VALUE klass) +{ + rb_classext_t *ext = ALLOC(rb_classext_t); + NEWOBJ(obj, struct RClass); + OBJSETUP(obj, klass, flags); + obj->ptr = ext; + RCLASS_IV_TBL(obj) = 0; + RCLASS_M_TBL(obj) = 0; + RCLASS_SUPER(obj) = 0; + RCLASS_IV_INDEX_TBL(obj) = 0; + return (VALUE)obj; +} +#endif + +inline static VALUE +create_class(VALUE flags, VALUE klass) +{ +#ifdef RUBY_19 + VALUE new_klass = class_alloc(flags, klass); +#else + NEWOBJ(new_klass, struct RClass); + OBJSETUP(new_klass, klass, flags); +#endif + + return (VALUE)new_klass; +} + +# define FALSE 0 +# define TRUE 1 + +/* a useful macro. cannot use ordinary CLASS_OF as it does not return an lvalue */ +#define KLASS_OF(c) (RBASIC(c)->klass) + +#endif diff --git a/ext/tcl_ruby/tcl_ruby.c b/ext/tcl_ruby/tcl_ruby.c index 6ed3dff..a831d52 100644 --- a/ext/tcl_ruby/tcl_ruby.c +++ b/ext/tcl_ruby/tcl_ruby.c @@ -1,5 +1,6 @@ #include #include +#include "compat.h" typedef struct { Tcl_Interp *interp; @@ -20,12 +21,12 @@ static VALUE rb_tcl_interp_send_begin(VALUE args) { VALUE obj = rb_ary_entry(args, 0); VALUE interp_receive_args = rb_ary_entry(args, 1); - VALUE result = rb_funcall2(obj, rb_intern("interp_receive"), RARRAY(interp_receive_args)->len, RARRAY(interp_receive_args)->ptr); + VALUE result = rb_funcall2(obj, rb_intern("interp_receive"), RARRAY_LEN(interp_receive_args), RARRAY_PTR(interp_receive_args)); tcl_interp_struct *tcl_interp; Data_Get_Struct(obj, tcl_interp_struct, tcl_interp); - char *tcl_result = strdup(RSTRING(rb_value_to_s(result))->ptr); + char *tcl_result = strdup(RSTRING_PTR(rb_value_to_s(result))); Tcl_SetResult(tcl_interp->interp, tcl_result, (Tcl_FreeProc *)free); return Qtrue; @@ -36,7 +37,7 @@ static VALUE rb_tcl_interp_send_rescue(VALUE args, VALUE error_info) { tcl_interp_struct *tcl_interp; Data_Get_Struct(obj, tcl_interp_struct, tcl_interp); - char *tcl_result = strdup(RSTRING(rb_value_to_s(error_info))->ptr); + char *tcl_result = strdup(RSTRING_PTR(rb_value_to_s(error_info))); Tcl_SetResult(tcl_interp->interp, tcl_result, (Tcl_FreeProc *)free); if (rb_obj_is_kind_of(error_info, rb_eSystemExit)) { @@ -97,7 +98,7 @@ static VALUE rb_tcl_interp_eval(VALUE self, VALUE args) { VALUE script = rb_ary_entry(args, 0); int timeout = 0; - if (RARRAY(args)->len == 2) { + if (RARRAY_LEN(args) == 2) { timeout = NUM2INT(rb_ary_entry(args, 1)); } #else @@ -119,7 +120,7 @@ static VALUE rb_tcl_interp_eval(VALUE self, VALUE script) { } #endif - int result = Tcl_Eval(tcl_interp->interp, RSTRING(rb_value_to_s(script))->ptr); + int result = Tcl_Eval(tcl_interp->interp, RSTRING_PTR(rb_value_to_s(script))); VALUE error_class = rb_const_get(rb_const_get(rb_cObject, rb_intern("Tcl")), rb_intern("Error")); @@ -150,7 +151,7 @@ static VALUE rb_tcl_interp_list_to_array(VALUE self, VALUE list) { tcl_interp_struct *tcl_interp; Data_Get_Struct(self, tcl_interp_struct, tcl_interp); - Tcl_Obj *string = Tcl_NewStringObj(RSTRING(rb_value_to_s(list))->ptr, -1); + Tcl_Obj *string = Tcl_NewStringObj(RSTRING_PTR(rb_value_to_s(list)), -1); Tcl_IncrRefCount(string); int list_length, i; @@ -184,14 +185,14 @@ static VALUE rb_tcl_interp_array_to_list(VALUE self, VALUE array) { tcl_interp_struct *tcl_interp; Data_Get_Struct(self, tcl_interp_struct, tcl_interp); - int array_length = RARRAY(array)->len, i; + int array_length = RARRAY_LEN(array), i; Tcl_Obj *list = Tcl_NewObj(); Tcl_IncrRefCount(list); for (i = 0; i < array_length; i++) { VALUE element = rb_ary_entry(array, i); - Tcl_Obj *string = Tcl_NewStringObj(RSTRING(rb_value_to_s(element))->ptr, -1); + Tcl_Obj *string = Tcl_NewStringObj(RSTRING_PTR(rb_value_to_s(element)), -1); Tcl_IncrRefCount(string); Tcl_ListObjAppendElement(tcl_interp->interp, list, string); diff --git a/tcl-0.0.1.gem b/tcl-0.0.1.gem new file mode 100644 index 0000000..2e3fb05 Binary files /dev/null and b/tcl-0.0.1.gem differ diff --git a/tcl-0.0.2.gem b/tcl-0.0.2.gem new file mode 100644 index 0000000..baba805 Binary files /dev/null and b/tcl-0.0.2.gem differ diff --git a/tcl.gemspec b/tcl.gemspec index e29179b..de3e0d6 100644 --- a/tcl.gemspec +++ b/tcl.gemspec @@ -4,58 +4,59 @@ # -*- encoding: utf-8 -*- Gem::Specification.new do |s| - s.name = %q{tcl} - s.version = "0.0.1" + s.name = "tcl" + s.version = "0.0.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Sam Stephenson"] + s.authors = ["Sam Stephenson", "John Mair (banisterfiend)"] s.date = %q{2009-12-01} s.description = %q{A minimal Ruby interface to libtcl} s.email = %q{sstephenson@gmail.com} s.extensions = ["ext/tcl_ruby/extconf.rb"] s.extra_rdoc_files = [ - "LICENSE", - "README.rdoc", - "TODO" - ] + "LICENSE", + "README.rdoc", + "TODO" + ] s.files = [ - ".gitignore", - "LICENSE", - "README.rdoc", - "Rakefile", - "TODO", - "VERSION", - "ext/tcl_ruby/extconf.rb", - "ext/tcl_ruby/tcl_ruby.c", - "lib/.gitignore", - "lib/tcl.rb", - "lib/tcl/interp.rb", - "lib/tcl/interp_helper.rb", - "lib/tcl/proc.rb", - "lib/tcl/var.rb", - "script/console", - "tcl.gemspec", - "test/fixtures/test.tcl", - "test/helper.rb", - "test/interp_receive_test.rb", - "test/interp_test.rb", - "test/proc_test.rb", - "test/test_helper.rb", - "test/var_test.rb" - ] + ".gitignore", + "LICENSE", + "README.rdoc", + "Rakefile", + "TODO", + "VERSION", + "ext/tcl_ruby/extconf.rb", + "ext/tcl_ruby/tcl_ruby.c", + "ext/tcl_ruby/compat.h", + "lib/.gitignore", + "lib/tcl.rb", + "lib/tcl/interp.rb", + "lib/tcl/interp_helper.rb", + "lib/tcl/proc.rb", + "lib/tcl/var.rb", + "script/console", + "tcl.gemspec", + "test/fixtures/test.tcl", + "test/helper.rb", + "test/interp_receive_test.rb", + "test/interp_test.rb", + "test/proc_test.rb", + "test/test_helper.rb", + "test/var_test.rb" + ] s.homepage = %q{http://github.com/sstephenson/ruby-tcl} s.rdoc_options = ["--charset=UTF-8"] s.require_paths = ["lib"] s.rubygems_version = %q{1.3.5} s.summary = %q{Tcl bindings for Ruby} s.test_files = [ - "test/helper.rb", - "test/interp_receive_test.rb", - "test/interp_test.rb", - "test/proc_test.rb", - "test/test_helper.rb", - "test/var_test.rb" - ] + "test/helper.rb", + "test/interp_receive_test.rb", + "test/interp_test.rb", + "test/proc_test.rb", + "test/test_helper.rb", + "test/var_test.rb" + ] if s.respond_to? :specification_version then current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION