RubyInline-3.12.2/0000755000004100000410000000000012202216036013701 5ustar www-datawww-dataRubyInline-3.12.2/test/0000755000004100000410000000000012202216036014660 5ustar www-datawww-dataRubyInline-3.12.2/test/test_inline.rb0000555000004100000410000005567112202216036017541 0ustar www-datawww-data$TESTING = true $0 = __FILE__ if $0 =~ /-e|\(eval\)|^$/ $0 = $0.sub(Dir.pwd, '.') require 'inline' require 'tempfile' require 'tmpdir' require 'fileutils' unless defined?(::FileUtils) require 'minitest/autorun' File.umask(0) require 'pathname' $inline_path = './lib/inline.rb' $test_inline_path = './test/test_inline.rb' class InlineTestCase < MiniTest::Unit::TestCase def setup super @rootdir = File.join(Dir.tmpdir, "test_inline.#{$$}") Dir.mkdir @rootdir, 0700 unless test ?d, @rootdir ENV['INLINEDIR'] = @rootdir end def teardown unless $DEBUG then FileUtils.rm_rf @rootdir ENV.delete 'INLINEDIR' end end end class TestDir < InlineTestCase def setup super @count = 1 end def util_assert_secure(perms, should_pass) path = File.join(@rootdir, @count.to_s) @count += 1 Dir.mkdir path, perms unless perms.nil? if should_pass then Dir.assert_secure path else assert_raises(SecurityError) do Dir.assert_secure path end end end def test_assert_secure # existing/good util_assert_secure 0700, true # existing/bad util_assert_secure 0707, false util_assert_secure 0770, false util_assert_secure 0777, false # missing util_assert_secure nil, true end end unless Inline::WINDOZE class TestInline < InlineTestCase def test_rootdir assert_equal(@rootdir, Inline.rootdir) end def test_directory version = "#{Gem.ruby_engine}-#{RbConfig::CONFIG['ruby_version']}" inlinedir = File.join(@rootdir, ".ruby_inline", version) assert_equal(inlinedir, Inline.directory) end end class TestInline class TestC < InlineTestCase def setup super @builder = Inline::C.new(self.class) end # quick hack to make tests more readable, # does nothing I wouldn't otherwise do... def inline(lang=:C) self.class.inline(lang, true) do |builder| yield(builder) end end def test_initialize x = Inline::C.new(self.class) assert_equal TestInline::TestC, x.mod assert_equal [], x.src assert_equal({}, x.sig) assert_equal [], x.flags assert_equal [], x.libs end def test_accessor builder = Inline::C.new self.class builder.struct_name = 'MyStruct' builder.accessor 'method_name', 'int' source = util_strip_lines builder.src expected = [] expected << <<-READER # line N "#{$inline_path}" static VALUE method_name(VALUE self) { MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); return (INT2FIX(pointer->method_name)); } READER expected << <<-WRITER # line N "#{$inline_path}" static VALUE method_name_equals(VALUE self, VALUE _value) { VALUE value = (_value); MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); pointer->method_name = FIX2INT(value); return (value); } WRITER assert_equal expected, source end def test_accessor_member_name builder = Inline::C.new self.class builder.struct_name = 'MyStruct' builder.accessor 'method_name', 'int', 'member_name' source = util_strip_lines builder.src expected = [] expected << <<-READER # line N "#{$inline_path}" static VALUE method_name(VALUE self) { MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); return (INT2FIX(pointer->member_name)); } READER expected << <<-WRITER # line N "#{$inline_path}" static VALUE method_name_equals(VALUE self, VALUE _value) { VALUE value = (_value); MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); pointer->member_name = FIX2INT(value); return (value); } WRITER assert_equal expected, source end def test_accessor_no_struct_name builder = Inline::C.new self.class e = assert_raises RuntimeError do builder.accessor 'method_name', 'int' end assert_equal "struct name not set for reader method_name int", e.message end def test_add_type_converter builder = Inline::C.new self.class builder.add_type_converter 'my_type', 'ruby_type2my_type', 'my_type2ruby_type' assert_equal 'my_type2ruby_type', builder.c2ruby('my_type') assert_equal 'ruby_type2my_type', builder.ruby2c('my_type') end def test_alias_type_converter builder = Inline::C.new self.class builder.alias_type_converter 'long long', 'int64_t' assert_equal 'LL2NUM', builder.c2ruby('int64_t') assert_equal 'NUM2LL', builder.ruby2c('int64_t') end def test_reader builder = Inline::C.new self.class builder.struct_name = 'MyStruct' builder.reader 'method_name', 'int' source = util_strip_lines builder.src expected = [] expected << <<-READER # line N "#{$inline_path}" static VALUE method_name(VALUE self) { MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); return (INT2FIX(pointer->method_name)); } READER assert_equal expected, source end def test_reader_member_name builder = Inline::C.new self.class builder.struct_name = 'MyStruct' builder.reader 'method_name', 'int', 'member_name' source = util_strip_lines builder.src expected = [] expected << <<-READER # line N "#{$inline_path}" static VALUE method_name(VALUE self) { MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); return (INT2FIX(pointer->member_name)); } READER assert_equal expected, source end def test_reader_no_struct_name builder = Inline::C.new self.class e = assert_raises RuntimeError do builder.reader 'method_name', 'int' end assert_equal "struct name not set for reader method_name int", e.message end def test_remove_type_converter builder = Inline::C.new self.class builder.remove_type_converter 'long' assert_raises ArgumentError do builder.c2ruby 'long' end end def test_writer builder = Inline::C.new self.class builder.struct_name = 'MyStruct' builder.writer 'method_name', 'int' source = util_strip_lines builder.src expected = [] expected << <<-WRITER # line N "#{$inline_path}" static VALUE method_name_equals(VALUE self, VALUE _value) { VALUE value = (_value); MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); pointer->method_name = FIX2INT(value); return (value); } WRITER assert_equal expected, source end def test_writer_member_name builder = Inline::C.new self.class builder.struct_name = 'MyStruct' builder.writer 'method_name', 'int', 'member_name' source = util_strip_lines builder.src expected = [] expected << <<-WRITER # line N "#{$inline_path}" static VALUE method_name_equals(VALUE self, VALUE _value) { VALUE value = (_value); MyStruct *pointer; Data_Get_Struct(self, MyStruct, pointer); pointer->member_name = FIX2INT(value); return (value); } WRITER assert_equal expected, source end def test_writer_no_struct_name builder = Inline::C.new self.class e = assert_raises RuntimeError do builder.writer 'method_name', 'int' end assert_equal "struct name not set for writer method_name int", e.message end def test_ruby2c x = Inline::C.new(self.class) assert_equal 'NUM2CHR', x.ruby2c("char") assert_equal 'StringValuePtr', x.ruby2c("char *") assert_equal "FI\X2INT", x.ruby2c("int") assert_equal 'NUM2UINT', x.ruby2c("unsigned") assert_equal 'NUM2UINT', x.ruby2c("unsigned int") assert_equal 'NUM2LONG', x.ruby2c("long") assert_equal 'NUM2ULONG', x.ruby2c("unsigned long") assert_equal 'NUM2LL', x.ruby2c("long long") assert_equal 'NUM2ULL', x.ruby2c("unsigned long long") assert_equal 'NUM2DBL', x.ruby2c("double") assert_equal 'NUM2OFFT', x.ruby2c("off_t") assert_equal '', x.ruby2c("VALUE") assert_raises ArgumentError do x.ruby2c('blah') end end def test_c2ruby x = Inline::C.new(self.class) assert_equal 'CHR2FIX', x.c2ruby("char") assert_equal 'rb_str_new2', x.c2ruby("char *") assert_equal 'INT2FIX', x.c2ruby("int") assert_equal 'UINT2NUM', x.c2ruby("unsigned int") assert_equal 'UINT2NUM', x.c2ruby("unsigned") assert_equal 'LONG2NUM', x.c2ruby("long") assert_equal 'ULONG2NUM', x.c2ruby("unsigned long") assert_equal 'LL2NUM', x.c2ruby("long long") assert_equal 'ULL2NUM', x.c2ruby("unsigned long long") assert_equal 'rb_float_new', x.c2ruby("double") assert_equal 'OFFT2NUM', x.c2ruby("off_t") assert_equal '', x.c2ruby("VALUE") assert_raises ArgumentError do x.c2ruby('blah') end end def util_module_name(*signatures) md5 = Digest::MD5.new signatures.each do |signature| @builder.sig[signature] = [nil, 0] md5 << signature.to_s end assert_equal("Inline_TestInline__TestC_#{md5}", @builder.module_name) end def test_module_name_0_methods util_module_name end def test_module_name_1_method util_module_name :something1 end def test_module_name_2_methods util_module_name :something2, :something3 end def test_module_name_2_other_methods util_module_name :something4, :something5 end def util_parse_signature(src, expected, t=nil, a=nil, b=nil) result = nil @builder.add_type_converter t, a, b unless t.nil? result = @builder.parse_signature(src) assert_equal(expected, result) end def test_parse_signature src = "// stupid cpp comment #include \"header.h\" /* stupid c comment */ int add(int x, int y) { int result = x+y; return result; } " expected = { 'name' => 'add', 'return' => 'int', 'arity' => 2, 'args' => [ ['x', 'int'], ['y', 'int'] ] } util_parse_signature(src, expected) end def test_parse_signature_custom src = "// stupid cpp comment #include \"header.h\" /* stupid c comment */ int add(fooby x, int y) { int result = x+y; return result; } " expected = { 'name' => 'add', 'return' => 'int', 'arity' => 2, 'args' => [ [ 'x', 'fooby' ], ['y', 'int'] ] } util_parse_signature(src, expected, "fooby", "r2c_fooby", "c2r_fooby") end def test_parse_signature_register src = "// stupid cpp comment #include \"header.h\" /* stupid c comment */ int add(register int x, int y) { int result = x+y; return result; } " expected = { 'name' => 'add', 'return' => 'int', 'arity' => 2, 'args' => [ [ 'x', 'register int' ], ['y', 'int'] ] } util_parse_signature(src, expected, "register int", "FI\X2INT", "INT2FI\X") end def util_generate(src, expected, expand_types=true) result = @builder.generate src, expand_types result = util_strip_lines result expected = "# line N \"#{$0}\"\n" + expected assert_equal(expected, result) end def util_generate_raw(src, expected) util_generate(src, expected, false) end def util_strip_lines(src) case src when String then src.gsub(/\# line \d+/, '# line N').gsub(Dir.pwd, '.') when Array then src.map do |chunk| util_strip_lines chunk end end end # Ruby Arity Rules, from the mouth of Matz: # -2 = ruby array argv # -1 = c array argv # 0 = self # 1 = self, value # 2 = self, value, value # ... # 16 = self, value * 15 def test_generate_raw_arity_0 src = "VALUE y(VALUE self) {blah;}" expected = "static VALUE y(VALUE self) {blah;}" util_generate_raw(src, expected) end def test_generate_arity_0 src = "int y() { do_something; return 42; }" expected = "static VALUE y(VALUE self) {\n do_something; return INT2FIX(42); }" util_generate(src, expected) end def test_generate_arity_0_no_return src = "void y() { do_something; }" expected = "static VALUE y(VALUE self) {\n do_something;\nreturn Qnil;\n}" util_generate(src, expected) end def test_generate_arity_0_void_return src = "void y(void) {go_do_something_external;}" expected = "static VALUE y(VALUE self) { go_do_something_external;\nreturn Qnil;\n}" util_generate(src, expected) end def test_generate_arity_0_int_return src = "int x() {return 42}" expected = "static VALUE x(VALUE self) { return INT2FIX(42)}" util_generate(src, expected) end def test_generate_raw_arity_1 src = "VALUE y(VALUE self, VALUE obj) {blah;}" expected = "static VALUE y(VALUE self, VALUE obj) {blah;}" util_generate_raw(src, expected) end def test_generate_arity_1 src = "int y(int x) {blah; return x+1;}" expected = "static VALUE y(VALUE self, VALUE _x) {\n int x = FIX2INT(_x);\nblah; return INT2FIX(x+1);}" util_generate(src, expected) end def test_generate_arity_1_no_return src = "void y(int x) {blah;}" expected = "static VALUE y(VALUE self, VALUE _x) {\n int x = FIX2INT(_x);\nblah;\nreturn Qnil;\n}" util_generate(src, expected) end def test_generate_raw_arity_2 src = "VALUE func(VALUE self, VALUE obj1, VALUE obj2) {blah;}" expected = "static VALUE func(VALUE self, VALUE obj1, VALUE obj2) {blah;}" util_generate_raw(src, expected) end def test_generate_arity_2 src = "int func(int x, int y) {blah; return x+y;}" expected = "static VALUE func(VALUE self, VALUE _x, VALUE _y) {\n int x = FIX2INT(_x);\n int y = FIX2INT(_y);\nblah; return INT2FIX(x+y);}" util_generate(src, expected) end def test_generate_raw_arity_3 src = "VALUE func(VALUE self, VALUE obj1, VALUE obj2, VALUE obj3) {blah;}" expected = "static VALUE func(VALUE self, VALUE obj1, VALUE obj2, VALUE obj3) {blah;}" util_generate_raw(src, expected) end def test_generate_arity_too_many src = "int too_many(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int aA, int aB, int aC, int aD, int aE, int aF, int ugh) { int q = v + w; return q+x+y+z; }" assert_raises ArgumentError do @builder.generate src, true end end def test_generate_comments src = "// stupid cpp comment /* stupid c comment */ int add(int x, int y) { // add two numbers return x+y; } " expected = "static VALUE add(VALUE self, VALUE _x, VALUE _y) { int x = FIX2INT(_x); int y = FIX2INT(_y); return INT2FIX(x+y); } " util_generate(src, expected) end def test_generate_local_header src = "// stupid cpp comment #include \"header\" /* stupid c comment */ int add(int x, int y) { // add two numbers return x+y; } " # FIX: should be 2 spaces before the return. Can't find problem. expected = "#include \"header\" static VALUE add(VALUE self, VALUE _x, VALUE _y) { int x = FIX2INT(_x); int y = FIX2INT(_y); return INT2FIX(x+y); } " util_generate(src, expected) end def test_generate_map_name src = "VALUE y_equals(VALUE self) {blah;}" expected = "static VALUE y_equals(VALUE self) {blah;}" util_generate_raw(src, expected) assert_equal [-1, nil, 'y='], @builder.sig['y_equals'] end def test_generate_system_header src = "// stupid cpp comment #include
/* stupid c comment */ int add(int x, int y) { // add two numbers return x+y; } " expected = "#include
static VALUE add(VALUE self, VALUE _x, VALUE _y) { int x = FIX2INT(_x); int y = FIX2INT(_y); return INT2FIX(x+y); } " util_generate(src, expected) end def test_generate_wonky_return src = "unsigned\nlong z(void) {return 42}" expected = "static VALUE z(VALUE self) { return ULONG2NUM(42)}" util_generate(src, expected) end def test_generate_compact src = "int add(int x, int y) {return x+y}" expected = "static VALUE add(VALUE self, VALUE _x, VALUE _y) { int x = FIX2INT(_x); int y = FIX2INT(_y); return INT2FIX(x+y)}" util_generate(src, expected) end def test_generate_char_star_normalize src = "char\n\*\n blah( char*s) {puts(s); return s}" expected = "static VALUE blah(VALUE self, VALUE _s) { char * s = StringValuePtr(_s); puts(s); return rb_str_new2(s)}" util_generate(src, expected) end def test_generate_ext @builder.c_singleton "VALUE allocate() { return Qnil; }" @builder.c "VALUE my_method() { return Qnil; }" @builder.prefix "static int x;" windoze = "\n __declspec(dllexport)" if Inline::WINDOZE expected = <<-EXT #include "ruby.h" static int x; # line N "#{$test_inline_path}" static VALUE allocate(VALUE self) { return (Qnil); } # line N "#{$test_inline_path}" static VALUE my_method(VALUE self) { return (Qnil); } #ifdef __cplusplus extern \"C\" { #endif#{windoze} void Init_Inline_TestInline__TestC_3ab8c09639e499394bb1f0a0194a839f() { VALUE c = rb_cObject; c = rb_const_get(c, rb_intern("TestInline")); c = rb_const_get(c, rb_intern("TestC")); rb_define_alloc_func(c, (VALUE(*)(VALUE))allocate); rb_define_method(c, "my_method", (VALUE(*)(ANYARGS))my_method, 0); } #ifdef __cplusplus } #endif EXT assert_equal expected, util_strip_lines(@builder.generate_ext) end def test_generate_ext_bad_allocate @builder.c_singleton "VALUE allocate(VALUE bad) { return Qnil; }" e = assert_raises RuntimeError do @builder.generate_ext end assert_equal 'TestInline::TestC::allocate must have an arity of zero', e.message end def test_c result = @builder.c "int add(int a, int b) { return a + b; }" expected = "# line N \"#{$0}\"\nstatic VALUE add(VALUE self, VALUE _a, VALUE _b) {\n int a = FIX2INT(_a);\n int b = FIX2INT(_b);\n return INT2FIX(a + b); }" result = util_strip_lines result assert_equal expected, result assert_equal [expected], util_strip_lines(@builder.src) end def test_c_raw src = "static VALUE answer_raw(int argc, VALUE *argv, VALUE self) { return INT2NUM(42); }" result = @builder.c_raw src.dup result = util_strip_lines result expected = "# line N \"#{$0}\"\n" + src assert_equal expected, result assert_equal [expected], util_strip_lines(@builder.src) end def test_map_c_const @builder.map_c_const :C_NAME => :int expected = [ " rb_define_const(c, \"C_NAME\", INT2FIX(C_NAME));" ] assert_equal expected, @builder.init_extra end def test_map_c_const_named @builder.map_c_const :C_NAME => [:int, :RUBY_NAME] expected = [ " rb_define_const(c, \"RUBY_NAME\", INT2FIX(C_NAME));" ] assert_equal expected, @builder.init_extra end # TODO: fix ? def util_simple_code(klassname, c_src) result = " require 'inline' class #{klassname} inline do |builder| builder.c <<-EOC #{c_src} EOC end end" result end def util_test_build(src) tempfile = Tempfile.new("util_test_build") tempfile.write src tempfile.close rb_file = tempfile.path + ".rb" File.rename tempfile.path, rb_file begin Kernel.module_eval { require rb_file } yield if block_given? ensure File.unlink rb_file end end def test_build_good skip "https://github.com/MagLev/maglev/issues/231" if maglev? code = util_simple_code(:DumbTest1, "long dumbpi() { return 314; }") util_test_build(code) do result = DumbTest1.new.dumbpi assert_equal(314, result) end end def test_build_bad code = util_simple_code(:DumbTest2, "void should_puke() { 1+1 2+2 }") assert_raises(CompilationError) do util_test_build(code) do flunk end end end def util_strip_comments(input) expect = 'line 1 #if 0 line 2 #endif line 3 ' assert_equal expect, @builder.strip_comments(input) end def test_strip_comments_cpp input = 'line 1 #if 0 line 2 #endif // 1 comment // 2 comment line 3 // trailing comment ' util_strip_comments(input) end def test_strip_comments_c input = 'line 1 #if 0 line 2 #endif /* * 1 comment * 2 comment */ line 3 /* trailing comment */ ' util_strip_comments(input) end def test_load # totally tested by test_build end end # class TestC end # class TestInline module Foo class Bar # inline stuff will go here... end end $test_module_code = <<-EOR module Foo class Bar inline do |builder| builder.c <<-EOC static int forty_two_instance() { return 42; } EOC builder.c_singleton <<-EOC static int twenty_four_class() { return 24; } EOC end end end EOR $test_module_code2 = <<-EOR require 'inline' # Demonstrates native functions in nested classes and # extending a class more than once from different ruby # source files module Foo class Bar inline do |builder| builder.c <<-EOC int twelve_instance() { return 12; } EOC builder.c_singleton <<-EOC int twelve_class() { return 12; } EOC end end end EOR class TestModule < InlineTestCase def test_nested skip "https://github.com/MagLev/maglev/issues/231" if maglev? Object.class_eval $test_module_code fb = Foo::Bar.new assert_equal(42, fb.forty_two_instance) assert_equal(24, Foo::Bar.twenty_four_class) tempfile = Tempfile.new("test_inline_nested") tempfile.write($test_module_code2) tempfile.flush tempfile.rewind FileUtils.cp tempfile.path, "#{tempfile.path}.rb" require "#{tempfile.path}.rb" assert_equal(12, fb.twelve_instance) assert_equal(12, Foo::Bar.twelve_class) FileUtils.rm "#{tempfile.path}.rb" end def test_argument_check_good skip "https://github.com/MagLev/maglev/issues/231" if maglev? util_arity_check fb = Foo::Bar.new assert_equal 13, fb.arity6(1, 2, 3, 4, 5, "blah") end def test_argument_check_fewer skip "https://github.com/MagLev/maglev/issues/231" if maglev? util_arity_check fb = Foo::Bar.new assert_raises ArgumentError do fb.arity6(1, 2, 3) end end def test_argument_check_more skip "https://github.com/MagLev/maglev/issues/231" if maglev? util_arity_check fb = Foo::Bar.new assert_raises ArgumentError do fb.arity6(1, 2, 3, 4, 5, "blah", :extra) end end def test_inline skip "https://github.com/MagLev/maglev/issues/231" if maglev? self.class.inline(:C) do |builder| builder.c "int add(int a, int b) { return a + b; }" end assert(test(?d, Inline.directory), "inline dir should have been created") matches = Dir[File.join(Inline.directory, "Inline_TestModule_*.c")] assert_equal(1, matches.length, "Source should have been created") library_file = matches.first.gsub(/\.c$/) { "." + RbConfig::CONFIG["DLEXT"] } assert(test(?f, library_file), "Library file should have been created") end def util_arity_check methods = Foo::Bar.public_instance_methods.map { |s| s.to_s } unless methods.include? "arity6" then Foo::Bar.inline do |builder| builder.include "" builder.c "int arity6(int u, int v, int w, int x, int y, char * z) { return x + y + strlen(z); }" end end end end RubyInline-3.12.2/demo/0000755000004100000410000000000012202216036014625 5ustar www-datawww-dataRubyInline-3.12.2/demo/fastmath.rb0000444000004100000410000000072512202216036016763 0ustar www-datawww-data begin require 'rubygems' rescue LoadError end require 'inline' class FastMath def factorial(n) f = 1 n.downto(2) { |x| f *= x } return f end inline do |builder| builder.c " long factorial_c(int max) { int i=max, result=1; while (i >= 2) { result *= i--; } return result; }" end end math = FastMath.new if ARGV.empty? then 30000.times do math.factorial(20); end else 30000.times do math.factorial_c(20); end end RubyInline-3.12.2/demo/hello.rb0000444000004100000410000000035512202216036016256 0ustar www-datawww-data#!/usr/local/bin/ruby -w begin require 'rubygems' rescue LoadError end require 'inline' class Hello inline do |builder| builder.include "" builder.c 'void hello() { puts("hello world"); }' end end Hello.new.hello RubyInline-3.12.2/Rakefile0000444000004100000410000000152612202216036015350 0ustar www-datawww-data# -*- ruby -*- require 'rubygems' require 'hoe' Hoe.add_include_dirs "../../ZenTest/dev/lib" Hoe.add_include_dirs "lib" Hoe.plugin :seattlerb Hoe.plugin :isolate Hoe.spec "RubyInline" do developer 'Ryan Davis', 'ryand-ruby@zenspider.com' clean_globs << File.expand_path("~/.ruby_inline") spec_extras[:requirements] = "A POSIX environment and a compiler for your language." dependency "ZenTest", "~> 4.3" # for ZenTest mapping end task :test => :clean desc "run all examples" task :examples do %w(example.rb example2.rb tutorial/example1.rb tutorial/example2.rb).each do |e| rm_rf '~/.ruby_inline' ruby "-Ilib -w #{e}" end end desc "run simple benchmarks" task :bench do verbose(false) do ruby "-Ilib ./example.rb" ruby "-Ilib ./example.rb 1000000 12" # 12 is the bignum cutoff for factorial end end RubyInline-3.12.2/History.txt0000444000004100000410000002623012202216036016104 0ustar www-datawww-data=== 3.12.2 / 2013-04-18 * 2 minor enhancements: * Added #prefix code to MD5 calculation to force rebuilds on non-signature changes. * Separated out #prefix code from #src. === 3.12.1 / 2013-02-14 * 2 bug fixes: * Fixes for maglev to find headers in the correct location. * Fixes for tests, mostly for maglev. === 3.12.0 / 2012-12-18 * 1 major enhancement: * map_ruby_const prefixes c-vars with 'c' (eg Name -> cName). * 1 minor enhancement: * Added #add_id to make interning symbols in C clean and easy === 3.11.4 / 2012-11-23 * 1 minor enhancement: * Improve windows compatibility (MinGW). (luislavena) === 3.11.3 / 2012-07-05 * 1 bug fix: * Fixes for non-mingw windoze builds. (imperator) === 3.11.2 / 2012-02-22 * 1 bug fix: * Added terrible hack to fix mingw's embedded make macros in rbconfig. (rdp) === 3.11.1 / 2012-01-25 * 1 bug fix: * Use Ruby's LDFLAGS config variable. (maharg) === 3.11.0 / 2011-09-27 * 1 major enhancement: * Removed Module#options === 3.10.1 / 2011-09-13 * 1 bug fix: * Fix crap_for_windoze to use RbConfig for RUBY_SO_NAME. (jasonrickman) === 3.10.0 / 2011-08-30 * 2 minor enhancements: * Added engined/versioned subdir to .ruby_inline to help with multiple-ruby usage. (valodzka) * Extended file/module naming to avoid hash collisions. (apohllo) * 2 bug fixes: * Fixed examples for 1.9 compatibility. * Use RbConfig instead of Config. (apohllo) === 3.9.0 / 2011-02-18 * 1 minor enhancement: * Added arity override option for all C builder methods. === 3.8.6 / 2010-09-03 * 1 bug fix: * Had to fix the ZenTest dependency to work with the whole 4.x series === 3.8.5 / 2010-09-01 * 1 bug fix: * Added DLDFLAGS to compiler flags to fix OSX linking on 1.9.2 === 3.8.4 / 2009-12-09 * 1 bug fix: * Clean up example.rb and force removal of ~/.ruby_inline === 3.8.3 / 2009-08-07 * 1 minor enhancement: * Added Inline::C#add_static to make consts cleaner === 3.8.2 / 2009-06-23 * 1 bug fix: * ruby 1.9 expands __FILE__ and broke my tests === 3.8.1 / 2008-10-24 * 1 minor enhancement * Inline registers all classes for hoe's INLINE=1 packaging feature. === 3.8.0 / 2008-10-22 * 8 minor enhancements: * Inline::C now uses ZenTestMapping to automatically map C functions to ruby names. * Inline::C#map_c_const can now map to a ruby constant name. * Added accessors for members of Data_Wrap_Structs. See Inline::C#accessor. * Added long long, unsigned long long, off_t types to built-in type map. * Added #alias_type_converter and #remove_type_converter. * Consider MinGW (mingw) as valid Windows platform. * Properly fallback to all the environment options under Windows. #22511. * Properly join path under OS with drive letters. #22292. * 1 bug fixes: * Inline::C now uses rb_define_alloc_func(). === 3.7.0 / 2008-06-09 * 1 major enhancements: * Removed inline_package in favor of hoe's packaging. * 2 minor enhancements: * Switched from warn/exit to abort to fix buffering for error messages. * Improved some error messages. * 2 bug fixes: * Fixes for rubinius. * Fixes for 1.9. === 3.6.7 / 2008-03-20 * 3 minor enhancements: * Added ability to work entirely without .ruby_inline dir. Thanks Kevin Clark! * Updated history, readme, and rakefile for new hoe abilities. * Cleaned up some really ugly schlock. Man, compiling sucks! * 2 bug fixes: * Fixes for 1.9. * Add -I for platform-specific header dir (for ruby/config.h). === 3.6.6 / 2007-12-27 * 1 minor enhancement: * Enhanced windows support thanks to Luis Lavena. === 3.6.5 / 2007-11-08 * 1 minor enhancement: * Quick fix for OSX 10.5 native ruby (should be fixed in 10.5.2). === 3.6.4 / 2007-08-20 * 1 minor enhancement: * Added ability to include ruby.h last. Thanks to Luc Heinrich. === 3.6.3 / 2007-04-27 * 7 minor enhancements: * Added map_ruby_const and map_c_const to C builder. * Converted example.rb to a real benchmark setup. * Improved error messages. * Added options hash for all C builder methods. * Options hash can take optional :method_name param to have ruby name diff from c. * Converted to a more traditional setup. Now I can heckle! * Cleaned up ruby.h search. * 2 bug fixes: * Added CCDLFLAGS. _Should_ pick up -fPIC on misconfigured 64 bit machines. * Broke up all warnings so progress report was cleaner. === 3.6.2 / 2006-10-12 * 2 bug fixes: * comment stripper much more sane to fix problems on certain linux distros * fixed a nit with older C compilers. === 3.6.1 / 2006-10-11 * 1 minor enhancement * Hoe'd the Rakefile. :P * 2 bug fixes * Removed VALUE from @types because it is now in @@type_map. * Tweak added for mingw32. === 3.6.0 / 2005-11-30 (omg I suck: actual release: 2006-09-15) * 6 minor enhancements * C builder can now be used directly for other foreign language glue. * Pretty much all (c) functions are plain argument style, not argc/argv. * Added Nathaniel and Dan's patches for windows support. * Added VALUE as a default known type. * Improved testing under $DEBUG. * Deprecated $INLINE_FLAGS and $INLINE_LIBS are dead. * 3 bug fixes * Fixed a number of issues wrt testing. * Cleaned up and cached certain calculations. * Some windows compiler fixes went in, but MS compiler is a PITA still. === 3.5.0 / 2005-10-15 * 4 minor enhancements * Switched to install for Makefile. * Lots of minor cleanup. * Added add_to_init to extend init methods. Great hack! * Added 2 demo files used in the rubyconf 2005 presentation. * 1 bug fix * Fixed example in README.txt. OOPS! === 3.4.0 / 2005-07-13 * 2 minor enhancement * Changed inline to take the language and a hash of options. * Still backwards compatible, for now, and emits a warning. * Options are available via the builder passed to your block. * 2 bug fixes * Modified caller discovery, yet again, due to changes in ruby 1.8.3. * More compatible and clean with non-gems systems. === 3.3.2 / 2005-05-19 * 4 bug fixes * Fixed a line number issue when using c_raw w/ multi-line signatures. * Inline can now be invoked multiple times per class. * Filled out rdoc. * Fixed some old tests. === 3.3.1 / 2005-05-03 * 3 bug fixes * Fixed a bug w/ unit tests involving caching of rootdir. * Added a minor tweak to the file discovery when called through eval. * Moved the packaging code into inline.rb in order to get rubygems wrapped scripts to work again (wrapper was breaking due to __FILE__ != $0). === 3.3.0 / 2005-04-22 * 2 minor enhancement * Added inline_package, which helps you package inlined code into gems. * inline_package also generates a Rakefile for you if you need it. * inline.rb now (only) loads packaged code when present. === 3.2.1 / 2005-04-19 * 2 bug fixes * Added double to typemap. Thanks Phil Tomson! * Added a minor hack to get cygwin to work right--lemme know pls. === 3.2.0 / 2004-11-27 * 8 minor enhancements * Gemified * Added #line preprocessor directives to make debugging inside your ruby file practical. * Added uninstall rule to Makefile * Inline::C now generates classes directly instead of included modules. * Better execeptions are thrown on error. * Incorporated a bunch of changes from Jonathan Paisley: * Generation of inline'd class methods. (c_singleton and c_raw_singleton) * Fixed problems with nested module/classes. * Inline can now extend the same class multiple times. * 2 bug fixes * Smarter require/instantiation to accomodate other languages better. * Fixed a logic error where running good code, then bad, then bad again ran the original good code. === 3.1.0 / 2004-09-24 * 2 minor enhancement * Extended API of Inline::C with prefix(code). * Documented all public API. * 2 bug fixes * Cleaned a lot of code and tests. * Removed nearly all tags. === 3.0.1 / 2004-02-24 * 2 bug fixes * I let references to ZenTestUnit slip through the release. Removed. * Converted History.txt to ZenWeb format. === 3.0.0 / 2003-12-23 * 3 major enhancements * Complete rewrite with new design. * Multiple language support, works with C/C++ out of the box. * Multiple functions per compilation unit, now allowing entire classes to be defined and linked in one unit. * Notes: * I still need to write much better/complete documentation. === 2.2.0 / 2003-01-25 * 1 minor enhancements * Touch all generated files to avoid unnecessary diffs. * 1 bug fixes * Added good profiling example in tutorial/*. * Added profiling strategy in README.txt. * Notes: * Paired with Doug Beaver === 2.1.1 / 2002-12-27 * 2 bug fixes * Fixed a bug in inline.rb where it was comparing against inline.rb, not the caller. * Tweaked example.rb to take the number of iterations as an option. === 2.1.0 / 2002-12-17 * 2 minor enhancements * Added inline_c_raw to replace Inline.inline. * Removed module Inline as a whole. This gets rid of some * major version incompatibilities, tons of duplicate code, and * just seems to make things happier. * 4 bug fixes * Added a fix from Michael Scholz to fix the use of $0 for file test. * Added private and public declarations since we are invading * class Module. * Fixed tests... oops! * Lots of clean up... * Notes: * Reviewed by Doug Beaver === 2.0.0 / 2002-12-12 * 2 bug fixes * Minor fix to get working on MacOS X (.so vs .bundle). * Downgraded typemap to be compatible with 1.6.x. * Notes: * Paired w/ Doug Beaver === 2.0.0 beta / 2002-11-22 * 1 major enhancements * Added inline_c, a "compile-time" version of inline. Massively enhanced, this version has a limited form of C function parsing. * 2 minor enhancements * Deprecated Inline#inline for Module#inline_c. To be removed by 2.1.0. * Extended example.rb to include a fully written inlined C function. * 3 bug fixes * Updated README.txt and improved some of the documentation. * Added test and clean rules to Makefile. * Removed the copious warnings if running ruby < 1.7.2. * Notes: * Paired w/ Doug Beaver === 1.1.0 / 2002-11-01 * 2 minor enhancements * Aliased methods are now inlined as well. 250x faster. * ONLY on ruby 1.7*. Warns on ruby < 1.7. * Added a makefile to automate running of all different benchmarks. * 1 bug fixes * Improved example to include an aliased method testcase. === 1.0.7 / 2002-09-22 * 1 minor enhancements * Only compiles the generated code if it was different from the previous version. * 1 bug fixes * Improved security: Checks group and global write on home directory. === 1.0.6 / 2002-09-18 * 1 minor enhancements * Added a prelude argument for header and datatype declarations. * 3 bug fixes * Only output stuff if invoked verbose (ie 'ruby -v ./example.rb'). * Added some compatibility code for windows. * Declared requirement on POSIX system. === 1.0.5 / 2002-09-11 * 2 bug fixes * Improved security model for UNIX. Still not sure about windoze. * Fixed History.txt to be accurate, gave example in README. === 1.0.4 / 2002-09-10 * 1 major enhancements * Released to sourceforge! * 1 bug fixes * A number of very minor bug fixes from IRC sessions w/ others. === 1.0.0 / 2002-09-05 * 1 major enhancements * Birthday! RubyInline-3.12.2/.gemtest0000644000004100000410000000000012202216036015340 0ustar www-datawww-dataRubyInline-3.12.2/metadata.yml0000644000004100000410000001055112202216036016206 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: RubyInline version: !ruby/object:Gem::Version hash: 51 prerelease: segments: - 3 - 12 - 2 version: 3.12.2 platform: ruby authors: - Ryan Davis autorequire: bindir: bin cert_chain: - | -----BEGIN CERTIFICATE----- MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB GRYDY29tMB4XDTA5MDMwNjE4NTMxNVoXDTEwMDMwNjE4NTMxNVowRTETMBEGA1UE AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB AQAY59gYvDxqSqgC92nAP9P8dnGgfZgLxP237xS6XxFGJSghdz/nI6pusfCWKM8m vzjjH2wUMSSf3tNudQ3rCGLf2epkcU13/rguI88wO6MrE0wi4ZqLQX+eZQFskJb/ w6x9W1ur8eR01s397LSMexySDBrJOh34cm2AlfKr/jokKCTwcM0OvVZnAutaovC0 l1SVZ0ecg88bsWHA0Yhh7NFxK1utWoIhtB6AFC/+trM0FQEB/jZkIS8SaNzn96Rl n0sZEf77FLf5peR8TP/PtmIg7Cyqz23sLM4mCOoTGIy5OcZ8TdyiyINUHtb5ej/T FBHgymkyj/AOSqKRIpXPhjC6 -----END CERTIFICATE----- date: 2013-04-18 00:00:00 Z dependencies: - !ruby/object:Gem::Dependency name: ZenTest prerelease: false requirement: &id001 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 29 segments: - 4 - 3 version: "4.3" type: :runtime version_requirements: *id001 - !ruby/object:Gem::Dependency name: minitest prerelease: false requirement: &id002 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 21 segments: - 4 - 7 version: "4.7" type: :development version_requirements: *id002 - !ruby/object:Gem::Dependency name: rdoc prerelease: false requirement: &id003 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 27 segments: - 4 - 0 version: "4.0" type: :development version_requirements: *id003 - !ruby/object:Gem::Dependency name: hoe prerelease: false requirement: &id004 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 11 segments: - 3 - 6 version: "3.6" type: :development version_requirements: *id004 description: |- Inline allows you to write foreign code within your ruby code. It automatically determines if the code in question has changed and builds it only when necessary. The extensions are then automatically loaded into the class/module that defines it. You can even write extra builders that will allow you to write inlined code in any language. Use Inline::C as a template and look at Module#inline for the required API. email: - ryand-ruby@zenspider.com executables: [] extensions: [] extra_rdoc_files: - History.txt - Manifest.txt - README.txt files: - History.txt - Manifest.txt - README.txt - Rakefile - demo/fastmath.rb - demo/hello.rb - example.rb - example2.rb - lib/inline.rb - test/test_inline.rb - tutorial/example1.rb - tutorial/example2.rb - .gemtest homepage: http://www.zenspider.com/ZSS/Products/RubyInline/ licenses: [] post_install_message: rdoc_options: - --main - README.txt require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" requirements: - A POSIX environment and a compiler for your language. rubyforge_project: rubyinline rubygems_version: 1.8.25 signing_key: specification_version: 3 summary: Inline allows you to write foreign code within your ruby code test_files: - test/test_inline.rb RubyInline-3.12.2/metadata.gz.sig0000644000004100000410000000040012202216036016576 0ustar www-datawww-dataMR} X;wݔ'֥x2a16&,SGד׼ uWGd)/N0Bsu#9`[=S}clÒ| A=rP:>f?H&;^ 1`" ~(&VՖ'Ƨ~\F=BA!R|vRk hTz՚$eMdz2}i6oLSvŐ^EY"Kv]͎Qk+dRubyInline-3.12.2/Manifest.txt0000444000004100000410000000025712202216036016212 0ustar www-datawww-dataHistory.txt Manifest.txt README.txt Rakefile demo/fastmath.rb demo/hello.rb example.rb example2.rb lib/inline.rb test/test_inline.rb tutorial/example1.rb tutorial/example2.rb RubyInline-3.12.2/data.tar.gz.sig0000644000004100000410000000040012202216036016514 0ustar www-datawww-dataolb+@aV3kV GL]i`u~&n]#7W%g}fZ2jm1 w"v|K?bѮ?'TL=[P+~2DBtΞk&O}frM_lVgJevVĚ3D|/ӌsKg8x3 ~xfh\6_ `m+Mi;w#RubyInline-3.12.2/example.rb0000555000004100000410000000316212202216036015664 0ustar www-datawww-data#!/usr/local/bin/ruby -w require 'rubygems' $:.unshift 'lib' require 'inline' require 'fileutils' FileUtils.rm_rf File.expand_path("~/.ruby_inline") class MyTest def factorial(n) f = 1 n.downto(2) { |x| f *= x } f end inline do |builder| builder.c " long factorial_c(int max) { int i=max, result=1; while (i >= 2) { result *= i--; } return result; }" builder.c_raw " static VALUE factorial_c_raw(int argc, VALUE *argv, VALUE self) { int i=FIX2INT(argv[0]), result=1; while (i >= 2) { result *= i--; } return INT2NUM(result); }" end end # breakeven for build run vs native doing 5 factorial: # on a PIII/750 running FreeBSD: about 5000 # on a PPC/G4/800 running Mac OSX 10.2: always faster require 'benchmark' puts "RubyInline #{Inline::VERSION}" if $DEBUG MyTest.send(:alias_method, :factorial_alias, :factorial_c_raw) t = MyTest.new() max = (ARGV.shift || 1_000_000).to_i n = (ARGV.shift || 5).to_i m = t.factorial(n) def validate(n, m) if n != m then raise "#{n} != #{m}"; end end puts "# of iterations = #{max}, n = #{n}" Benchmark::bm(20) do |x| x.report("null_time") do for i in 0..max do # do nothing end end x.report("c") do for i in 0..max do validate(t.factorial_c(n), m) end end x.report("c-raw") do for i in 0..max do validate(t.factorial_c_raw(n), m) end end x.report("c-alias") do for i in 0..max do validate(t.factorial_alias(n), m) end end x.report("pure ruby") do for i in 0..max do validate(t.factorial(n), m) end end end RubyInline-3.12.2/example2.rb0000555000004100000410000000063512202216036015750 0ustar www-datawww-data#!/usr/local/bin/ruby17 -w begin require 'rubygems' rescue LoadError $: << 'lib' end require 'inline' class MyTest inline do |builder| builder.add_compile_flags %q(-x c++) builder.add_link_flags %q(-lstdc++) builder.include "" builder.c " static void hello(int i) { while (i-- > 0) { std::cout << \"hello\" << std::endl; } } " end end t = MyTest.new() t.hello(3) RubyInline-3.12.2/README.txt0000444000004100000410000001060012202216036015372 0ustar www-datawww-data= Ruby Inline rdoc :: http://docs.seattlerb.org/RubyInline/ home :: http://www.zenspider.com/ZSS/Products/RubyInline/ repo :: https://github.com/seattlerb/rubyinline == DESCRIPTION: Inline allows you to write foreign code within your ruby code. It automatically determines if the code in question has changed and builds it only when necessary. The extensions are then automatically loaded into the class/module that defines it. You can even write extra builders that will allow you to write inlined code in any language. Use Inline::C as a template and look at Module#inline for the required API. == PACKAGING: To package your binaries into a gem, use hoe's INLINE and FORCE_PLATFORM env vars. Example: rake package INLINE=1 or: rake package INLINE=1 FORCE_PLATFORM=mswin32 See hoe for more details. == FEATURES/PROBLEMS: * Quick and easy inlining of your C or C++ code embedded in your ruby script. * Extendable to work with other languages. * Automatic conversion between ruby and C basic types * char, unsigned, unsigned int, char *, int, long, unsigned long * inline_c_raw exists for when the automatic conversion isn't sufficient. * Only recompiles if the inlined code has changed. * Pretends to be secure. * Only requires standard ruby libraries, nothing extra to download. == SYNOPSIS: require "inline" class MyTest inline do |builder| builder.c " long factorial(int max) { int i=max, result=1; while (i >= 2) { result *= i--; } return result; }" end end t = MyTest.new() factorial_5 = t.factorial(5) == SYNOPSIS (C++): require 'inline' class MyTest inline(:C) do |builder| builder.include '' builder.add_compile_flags '-x c++', '-lstdc++' builder.c ' void hello(int i) { while (i-- > 0) { std::cout << "hello" << std::endl; } }' end end t = MyTest.new() t.hello(3) == (PSEUDO)BENCHMARKS: > make bench Running native Type = Native , Iter = 1000000, T = 28.70058100 sec, 0.00002870 sec / iter Running primer - preloads the compiler and stuff With full builds Type = Inline C , Iter = 1000000, T = 7.55118600 sec, 0.00000755 sec / iter Type = InlineRaw, Iter = 1000000, T = 7.54488300 sec, 0.00000754 sec / iter Type = Alias , Iter = 1000000, T = 7.53243100 sec, 0.00000753 sec / iter Without builds Type = Inline C , Iter = 1000000, T = 7.59543300 sec, 0.00000760 sec / iter Type = InlineRaw, Iter = 1000000, T = 7.54097200 sec, 0.00000754 sec / iter Type = Alias , Iter = 1000000, T = 7.53654000 sec, 0.00000754 sec / iter == PROFILING STRATEGY: 0) Always keep a log of your progress and changes. 1) Run code with 'time' and large dataset. 2) Run code with '-rprofile' and smaller dataset, large enough to get good #s. 3) Examine profile output and translate 1 bottleneck to C. 4) Run new code with 'time' and large dataset. Repeat 2-3 if unsatisfied. 5) Run final code with 'time' and compare to the first run. == REQUIREMENTS: * Ruby - 1.8.2 has been used on FreeBSD 4.6+ and MacOSX. * POSIX compliant system (ie pretty much any UNIX, or Cygwin on MS platforms). * A C/C++ compiler (the same one that compiled your ruby interpreter). * test::unit for running tests ( http://testunit.talbott.ws/ ). == INSTALL: * make test (optional) * make install == LICENSE: (The MIT License) Copyright (c) Ryan Davis, seattle.rb Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. RubyInline-3.12.2/lib/0000755000004100000410000000000012202216036014447 5ustar www-datawww-dataRubyInline-3.12.2/lib/inline.rb0000444000004100000410000006327512202216036016265 0ustar www-datawww-data#!/usr/local/bin/ruby -w ## # Ruby Inline is a framework for writing ruby extensions in foreign # languages. # # == SYNOPSIS # # require 'inline' # class MyClass # inline do |builder| # builder.include "" # builder.c %q{ # long factorial(int max) { # int i=max, result=1; # while (i >= 2) { result *= i--; } # return result; # } # } # end # end # # == DESCRIPTION # # Inline allows you to write foreign code within your ruby code. It # automatically determines if the code in question has changed and # builds it only when necessary. The extensions are then automatically # loaded into the class/module that defines it. # # You can even write extra builders that will allow you to write # inlined code in any language. Use Inline::C as a template and look # at Module#inline for the required API. # # == PACKAGING # # To package your binaries into a gem, use hoe's INLINE and # FORCE_PLATFORM env vars. # # Example: # # rake package INLINE=1 # # or: # # rake package INLINE=1 FORCE_PLATFORM=mswin32 # # See hoe for more details. # require "rbconfig" require "digest/md5" require 'fileutils' require 'rubygems' require 'zentest_mapping' $TESTING = false unless defined? $TESTING class CompilationError < RuntimeError; end ## # The Inline module is the top-level module used. It is responsible # for instantiating the builder for the right language used, # compilation/linking when needed, and loading the inlined code into # the current namespace. module Inline VERSION = "3.12.2" WINDOZE = /mswin|mingw/ =~ RUBY_PLATFORM RUBINIUS = defined? RUBY_ENGINE DEV_NULL = (WINDOZE ? 'nul' : '/dev/null') GEM = 'gem' RAKE = if RUBINIUS then File.join(Gem.bindir, 'rake') else "#{Gem.ruby} -S rake" end warn "RubyInline v #{VERSION}" if $DEBUG def self.register cls registered_inline_classes << cls registered_inline_classes.uniq! end def self.registered_inline_classes @@registered_inline_classes ||= [] end # rootdir can be forced using INLINEDIR variable # if not defined, it should store in user HOME folder # # Under Windows user data can be stored in several locations: # # HOME # HOMEDRIVE + HOMEPATH # APPDATA # USERPROFILE # # Perform a check in that other to see if the environment is defined # and if so, use it. only try this on Windows. def self.rootdir env = ENV['INLINEDIR'] || ENV['HOME'] if env.nil? and WINDOZE then # try HOMEDRIVE + HOMEPATH combination if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then env = ENV['HOMEDRIVE'] + ENV['HOMEPATH'] end # no HOMEDRIVE? use APPDATA env = ENV['APPDATA'] if env.nil? and ENV['APPDATA'] # bummer, still no env? then fall to USERPROFILE env = ENV['USERPROFILE'] if env.nil? and ENV['USERPROFILE'] end if env.nil? then abort "Define INLINEDIR or HOME in your environment and try again" end unless defined? @@rootdir and env == @@rootdir and test ?d, @@rootdir then rootdir = env Dir.mkdir rootdir, 0700 unless test ?d, rootdir Dir.assert_secure rootdir @@rootdir = rootdir end @@rootdir end def self.directory unless defined? @@directory then version = "#{Gem.ruby_engine}-#{RbConfig::CONFIG['ruby_version']}" @@directory = File.join(self.rootdir, ".ruby_inline", version) end Dir.assert_secure @@directory @@directory end ## # Inline::C is the default builder used and the only one provided by # Inline. It can be used as a template to write builders for other # languages. It understands type-conversions for the basic types and # can be extended as needed using #add_type_converter, #alias_type_converter # and #remove_type_converter. class C include ZenTestMapping MAGIC_ARITY_THRESHOLD = 15 MAGIC_ARITY = -1 ## # Default C to ruby and ruby to C type map TYPE_MAP = { 'char' => [ 'NUM2CHR', 'CHR2FIX' ], 'char *' => [ 'StringValuePtr', 'rb_str_new2' ], 'double' => [ 'NUM2DBL', 'rb_float_new' ], 'int' => [ "FI\X2INT", 'INT2FIX' ], 'unsigned int' => [ 'NUM2UINT', 'UINT2NUM' ], 'unsigned' => [ 'NUM2UINT', 'UINT2NUM' ], 'long' => [ 'NUM2LONG', 'LONG2NUM' ], 'unsigned long' => [ 'NUM2ULONG', 'ULONG2NUM' ], 'long long' => [ 'NUM2LL', 'LL2NUM' ], 'unsigned long long' => [ 'NUM2ULL', 'ULL2NUM' ], 'off_t' => [ 'NUM2OFFT', 'OFFT2NUM' ], 'VALUE' => [ '', '' ], # Can't do these converters because they conflict with the above: # ID2SYM(x), SYM2ID(x), F\IX2UINT(x) } def strip_comments(src) # strip c-comments src = src.gsub(%r%\s*/\*.*?\*/%m, '') # strip cpp-comments src = src.gsub(%r%^\s*//.*?\n%, '') src = src.gsub(%r%[ \t]*//[^\n]*%, '') src end def parse_signature(src, raw=false) sig = self.strip_comments(src) # strip preprocessor directives sig.gsub!(/^\s*\#.*(\\\n.*)*/, '') # strip {}s sig.gsub!(/\{[^\}]*\}/, '{ }') # clean and collapse whitespace sig.gsub!(/\s+/, ' ') unless defined? @types then @types = 'void|' + @type_map.keys.map{|x| Regexp.escape(x)}.join('|') end if /(#{@types})\s*(\w+)\s*\(([^)]*)\)/ =~ sig then return_type, function_name, arg_string = $1, $2, $3 args = [] arg_string.split(',').each do |arg| # helps normalize into 'char * varname' form arg = arg.gsub(/\s*\*\s*/, ' * ').strip if /(((#{@types})\s*\*?)+)\s+(\w+)\s*$/ =~ arg then args.push([$4, $1]) elsif arg != "void" then warn "WAR\NING: '#{arg}' not understood" end end arity = args.size arity = MAGIC_ARITY if raw return { 'return' => return_type, 'name' => function_name, 'args' => args, 'arity' => arity } end raise SyntaxError, "Can't parse signature: #{sig}" end # def parse_signature def generate(src, options={}) options = {:expand_types=>options} unless Hash === options expand_types = options[:expand_types] singleton = options[:singleton] result = self.strip_comments(src) signature = parse_signature(src, !expand_types) function_name = signature['name'] method_name = options[:method_name] method_name ||= test_to_normal function_name return_type = signature['return'] arity = options[:arity] || signature['arity'] raise ArgumentError, "too many arguments" if arity > MAGIC_ARITY_THRESHOLD if expand_types then prefix = "static VALUE #{function_name}(" if arity <= MAGIC_ARITY then prefix += "int argc, VALUE *argv, VALUE self" else prefix += "VALUE self" prefix += signature['args'].map { |arg, type| ", VALUE _#{arg}"}.join end prefix += ") {\n" prefix += signature['args'].map { |arg, type| " #{type} #{arg} = #{ruby2c(type)}(_#{arg});\n" }.join # replace the function signature (hopefully) with new sig (prefix) result.sub!(/[^;\/\"\>]+#{function_name}\s*\([^\{]+\{/, "\n" + prefix) result.sub!(/\A\n/, '') # strip off the \n in front in case we added it unless return_type == "void" then raise SyntaxError, "Couldn't find return statement for #{function_name}" unless result =~ /return/ result.gsub!(/return\s+([^\;\}]+)/) do "return #{c2ruby(return_type)}(#{$1})" end else result.sub!(/\s*\}\s*\Z/, "\nreturn Qnil;\n}") end else prefix = "static #{return_type} #{function_name}(" result.sub!(/[^;\/\"\>]+#{function_name}\s*\(/, prefix) result.sub!(/\A\n/, '') # strip off the \n in front in case we added it end delta = if result =~ /\A(static.*?\{)/m then $1.split(/\n/).size else msg = "WAR\NING: Can't find signature in #{result.inspect}\n" warn msg unless $TESTING 0 end file, line = $1, $2 if caller[1] =~ /(.*?):(\d+)/ result = "# line #{line.to_i + delta} \"#{file}\"\n" + result unless $DEBUG and not $TESTING @src << result @sig[function_name] = [arity,singleton,method_name] return result if $TESTING end # def generate ## # Builds a complete C extension suitable for writing to a file and # compiling. def generate_ext ext = [] if @include_ruby_first @inc.unshift "#include \"ruby.h\"" else @inc.push "#include \"ruby.h\"" end ext << @inc ext << nil unless @pre.empty? then ext << @pre.join("\n\n") ext << nil end ext << @src.join("\n\n") ext << nil ext << nil ext << "#ifdef __cplusplus" ext << "extern \"C\" {" ext << "#endif" ext << " __declspec(dllexport)" if WINDOZE ext << " void Init_#{module_name}() {" ext << " VALUE c = rb_cObject;" # TODO: use rb_class2path # ext << " VALUE c = rb_path2class(#{@mod.name.inspect});" ext << @mod.name.split("::").map { |n| " c = rb_const_get(c, rb_intern(\"#{n}\"));" }.join("\n") ext << nil @sig.keys.sort.each do |name| method = '' arity, singleton, method_name = @sig[name] if singleton then if method_name == 'allocate' then raise "#{@mod}::allocate must have an arity of zero" if arity > 0 ext << " rb_define_alloc_func(c, (VALUE(*)(VALUE))#{name});" next end method << " rb_define_singleton_method(c, \"#{method_name}\", " else method << " rb_define_method(c, \"#{method_name}\", " end method << "(VALUE(*)(ANYARGS))#{name}, #{arity});" ext << method end ext << @init_extra.join("\n") unless @init_extra.empty? ext << nil ext << " }" ext << "#ifdef __cplusplus" ext << "}" ext << "#endif" ext << nil ext.join "\n" end def module_name unless defined? @module_name then module_name = @mod.name.gsub('::','__') md5 = Digest::MD5.new @pre.each { |m| md5 << m.to_s } @sig.keys.sort_by { |x| x.to_s }.each { |m| md5 << m.to_s } @module_name = "Inline_#{module_name}_#{md5}" end @module_name end def so_name unless defined? @so_name then @so_name = "#{Inline.directory}/#{module_name}.#{RbConfig::CONFIG["DLEXT"]}" end @so_name end attr_reader :rb_file, :mod attr_writer :mod attr_accessor :src, :pre, :sig, :flags, :libs, :init_extra ## # Sets the name of the C struct for generating accessors. Used with # #accessor, #reader, #writer. attr_accessor :struct_name def initialize(mod) raise ArgumentError, "Class/Module arg is required" unless Module === mod # new (but not on some 1.8s) -> inline -> real_caller|eval stack = caller meth = stack.shift until meth =~ /in .(inline|test_|setup)/ or stack.empty? raise "Couldn't discover caller" if stack.empty? real_caller = stack.first real_caller = stack[3] if real_caller =~ /\(eval\)/ real_caller =~ /(.*):(\d+)/ real_caller = $1 @rb_file = File.expand_path real_caller @mod = mod @pre = [] @src = [] @inc = [] @sig = {} @flags = [] @libs = [] @init_extra = [] @include_ruby_first = true @inherited_methods = {} @struct_name = nil @type_map = TYPE_MAP.dup end ## # Adds a #reader and #writer for a C struct member wrapped via # Data_Wrap_Struct. +method+ is the ruby name to give the accessor, # +type+ is the C type. Unless the C member name is overridden with # +member+, the method name is used as the struct member. # # builder.struct_name = 'MyStruct' # builder.accessor :title, 'char *' # builder.accessor :stream_index, 'int', :index # # The latter accesses MyStruct->index via the stream_index method. def accessor(method, type, member = method) reader method, type, member writer method, type, member end ## # Adds a reader for a C struct member wrapped via Data_Wrap_Struct. # +method+ is the ruby name to give the reader, +type+ is the C type. # Unless the C member name is overridden with +member+, the method # name is used as the struct member. See #accessor for an example. def reader(method, type, member = method) raise "struct name not set for reader #{method} #{type}" unless @struct_name c <<-C VALUE #{method}() { #{@struct_name} *pointer; Data_Get_Struct(self, #{@struct_name}, pointer); return #{c2ruby type}(pointer->#{member}); } C end ## # Adds a writer for a C struct member wrapped via Data_Get_Struct. # +method+ is the ruby name to give the writer, +type+ is the C type. # Unless the C member name is overridden with +member+, the method # name is used as the struct member. See #accessor for an example. def writer(method, type, member = method) raise "struct name not set for writer #{method} #{type}" unless @struct_name c <<-C VALUE #{method}_equals(VALUE value) { #{@struct_name} *pointer; Data_Get_Struct(self, #{@struct_name}, pointer); pointer->#{member} = #{ruby2c type}(value); return value; } C end ## # Converts ruby type +type+ to a C type def ruby2c(type) raise ArgumentError, "Unknown type #{type.inspect}" unless @type_map.has_key? type @type_map[type].first end ## # Converts C type +type+ to a ruby type def c2ruby(type) raise ArgumentError, "Unknown type #{type.inspect}" unless @type_map.has_key? type @type_map[type].last end ## # Attempts to load pre-generated code returning true if it succeeds. def load_cache begin file = File.join("inline", File.basename(so_name)) if require file then dir = Inline.directory warn "WAR\NING: #{dir} exists but is not being used" if test ?d, dir and $VERBOSE return true end rescue LoadError end return false end ## # Loads the generated code back into ruby def load require "#{so_name}" or raise LoadError, "require on #{so_name} failed" end ## # Builds the source file, if needed, and attempts to compile it. def build so_name = self.so_name so_exists = File.file? so_name unless so_exists and File.mtime(rb_file) < File.mtime(so_name) then unless File.directory? Inline.directory then warn "NOTE: creating #{Inline.directory} for RubyInline" if $DEBUG FileUtils.mkdir_p Inline.directory, :mode => 0700 end src_name = "#{Inline.directory}/#{module_name}.c" old_src_name = "#{src_name}.old" should_compare = File.write_with_backup(src_name) do |io| io.puts generate_ext end # recompile only if the files are different recompile = true if so_exists and should_compare and FileUtils.compare_file(old_src_name, src_name) then recompile = false # Updates the timestamps on all the generated/compiled files. # Prevents us from entering this conditional unless the source # file changes again. t = Time.now File.utime(t, t, src_name, old_src_name, so_name) end if recompile then hdrdir = %w(srcdir includedir archdir rubyhdrdir).map { |name| RbConfig::CONFIG[name] }.find { |dir| dir and File.exist? File.join(dir, "ruby.h") } or abort "ERROR: Can't find header dir for ruby. Exiting..." flags = @flags.join(' ') libs = @libs.join(' ') config_hdrdir = if RUBY_VERSION > '1.9' then "-I #{File.join hdrdir, RbConfig::CONFIG['arch']}" else nil end windoze = WINDOZE and RUBY_PLATFORM =~ /mswin/ sane = ! windoze cmd = [ RbConfig::CONFIG['LDSHARED'], flags, (RbConfig::CONFIG['DLDFLAGS'] if sane), (RbConfig::CONFIG['CCDLFLAGS'] if sane), RbConfig::CONFIG['CFLAGS'], (RbConfig::CONFIG['LDFLAGS'] if sane), '-I', hdrdir, config_hdrdir, '-I', RbConfig::CONFIG['includedir'], ("-L#{RbConfig::CONFIG['libdir']}" if sane), (['-o', so_name.inspect] if sane), File.expand_path(src_name).inspect, libs, crap_for_windoze, (RbConfig::CONFIG['LDFLAGS'] if windoze), (RbConfig::CONFIG['CCDLFLAGS'] if windoze), ].compact.join(' ') # strip off some makefile macros for mingw 1.9 cmd = cmd.gsub(/\$\(.*\)/, '') if RUBY_PLATFORM =~ /mingw/ # TODO: remove after osx 10.5.2 cmd += ' -flat_namespace -undefined suppress' if RUBY_PLATFORM =~ /darwin9\.[01]/ cmd += " 2> #{DEV_NULL}" if $TESTING and not $DEBUG warn "Building #{so_name} with '#{cmd}'" if $DEBUG result = if WINDOZE Dir.chdir(Inline.directory) { `#{cmd}` } else `#{cmd}` end warn "Output:\n#{result}" if $DEBUG if $? != 0 then bad_src_name = src_name + ".bad" File.rename src_name, bad_src_name raise CompilationError, "error executing #{cmd.inspect}: #{$?}\nRenamed #{src_name} to #{bad_src_name}" end # NOTE: manifest embedding is only required when using VC8 ruby # build or compiler. # Errors from this point should be ignored if RbConfig::CONFIG['arch'] # (RUBY_PLATFORM) matches 'i386-mswin32_80' if WINDOZE and RUBY_PLATFORM =~ /_80$/ then Dir.chdir Inline.directory do cmd = "mt /manifest lib.so.manifest /outputresource:so.dll;#2" warn "Embedding manifest with '#{cmd}'" if $DEBUG result = `#{cmd}` warn "Output:\n#{result}" if $DEBUG if $? != 0 then raise CompilationError, "error executing #{cmd}: #{$?}" end end end warn "Built successfully" if $DEBUG end else warn "#{so_name} is up to date" if $DEBUG end # unless (file is out of date) end # def build ## # Returns extra compilation flags for windoze platforms. Ugh. def crap_for_windoze # gawd windoze land sucks case RUBY_PLATFORM when /mswin32/ then " -link /OUT:\"#{self.so_name}\" /LIBPATH:\"#{RbConfig::CONFIG['libdir']}\" /DEFAULTLIB:\"#{RbConfig::CONFIG['LIBRUBY']}\" /INCREMENTAL:no /EXPORT:Init_#{module_name}" when /mingw32/ then c = RbConfig::CONFIG " -Wl,--enable-auto-import -L#{c['libdir']} -l#{c['RUBY_SO_NAME']} -o #{so_name.inspect}" when /i386-cygwin/ then ' -L/usr/local/lib -lruby.dll' else '' end end ## # Adds compiler options to the compiler command line. No # preprocessing is done, so you must have all your dashes and # everything. def add_compile_flags(*flags) @flags.push(*flags) end ## # Registers a static id_name for the symbol :name. def add_id name self.add_static "id_#{name}", "rb_intern(\"#{name}\")" end ## # Adds linker flags to the link command line. No preprocessing is # done, so you must have all your dashes and everything. def add_link_flags(*flags) @libs.push(*flags) end ## # Create a static variable and initialize it to a value. def add_static name, init, type = "VALUE" prefix "static #{type} #{name};" add_to_init "#{name} = #{init};" end ## # Adds custom content to the end of the init function. def add_to_init(*src) @init_extra.push(*src) end ## # Registers C type-casts +r2c+ and +c2r+ for +type+. def add_type_converter(type, r2c, c2r) warn "WAR\NING: overridding #{type} on #{caller[0]}" if @type_map.has_key? type @type_map[type] = [r2c, c2r] end ## # Registers C type +alias_type+ as an alias of +existing_type+ def alias_type_converter(existing_type, alias_type) warn "WAR\NING: overridding #{type} on #{caller[0]}" if @type_map.has_key? alias_type @type_map[alias_type] = @type_map[existing_type] end ## # Unregisters C type-casts for +type+. def remove_type_converter(type) @type_map.delete type end ## # Maps RubyConstants to cRubyConstants. def map_ruby_const(*names) names.each do |name| self.prefix "static VALUE c#{name};" self.add_to_init " c#{name} = rb_const_get(c, rb_intern(#{name.to_s.inspect}));" end end ## # Maps a C constant to ruby. +names_and_types+ is a hash that maps the # name of the constant to its C type. # # builder.map_c_const :C_NAME => :int # # If you wish to give the constant a different ruby name: # # builder.map_c_const :C_NAME => [:int, :RUBY_NAME] def map_c_const(names_and_types) names_and_types.each do |name, typ| typ, ruby_name = Array === typ ? typ : [typ, name] self.add_to_init " rb_define_const(c, #{ruby_name.to_s.inspect}, #{c2ruby(typ.to_s)}(#{name}));" end end ## # Adds an include to the top of the file. Don't forget to use # quotes or angle brackets. def include(header) @inc << "#include #{header}" end ## # Specifies that the the ruby.h header should be included *after* custom # header(s) instead of before them. def include_ruby_last @include_ruby_first = false end ## # Adds any amount of text/code to the source def prefix(code) @pre << code end ## # Adds a C function to the source, including performing automatic # type conversion to arguments and the return value. The Ruby # method name can be overridden by providing method_name. Unknown # type conversions can be extended by using +add_type_converter+. def c src, options = {} options = { :expand_types => true, }.merge options self.generate src, options end ## # Same as +c+, but adds a class function. def c_singleton src, options = {} options = { :expand_types => true, :singleton => true, }.merge options self.generate src, options end ## # Adds a raw C function to the source. This version does not # perform any type conversion and must conform to the ruby/C # coding conventions. The Ruby method name can be overridden # by providing method_name. def c_raw src, options = {} self.generate src, options end ## # Same as +c_raw+, but adds a class function. def c_raw_singleton src, options = {} options = { :singleton => true, }.merge options self.generate src, options end end # class Inline::C end # module Inline class Module ## # Extends the Module class to have an inline method. The default # language/builder used is C, but can be specified with the +lang+ # parameter. def inline(lang = :C, options={}) Inline.register self case options when TrueClass, FalseClass then warn "WAR\NING: 2nd argument to inline is now a hash, changing to {:testing=>#{options}}" unless options options = { :testing => options } when Hash options[:testing] ||= false else raise ArgumentError, "BLAH" end builder_class = begin Inline.const_get(lang) rescue NameError require "inline/#{lang}" Inline.const_get(lang) end builder = builder_class.new self yield builder unless options[:testing] then unless builder.load_cache then builder.build builder.load end end end end class File ## # Equivalent to +File::open+ with an associated block, but moves # any existing file with the same name to the side first. def self.write_with_backup(path) # returns true if file already existed # move previous version to the side if it exists renamed = false if test ?f, path then renamed = true File.rename path, path + ".old" end File.open(path, "w") do |io| yield(io) end return renamed end end # class File class Dir ## # +assert_secure+ checks that if a +path+ exists it has minimally # writable permissions. If not, it prints an error and exits. It # only works on +POSIX+ systems. Patches for other systems are # welcome. def self.assert_secure(path) mode = File.stat(path).mode unless ((mode % 01000) & 0022) == 0 then if $TESTING then raise SecurityError, "Directory #{path} is insecure" else abort "#{path} is insecure (#{'%o' % mode}). It may not be group or world writable. Exiting." end end rescue Errno::ENOENT # If it ain't there, it's certainly secure end end RubyInline-3.12.2/tutorial/0000755000004100000410000000000012202216036015544 5ustar www-datawww-dataRubyInline-3.12.2/tutorial/example1.rb0000555000004100000410000000421512202216036017610 0ustar www-datawww-data#!/usr/bin/ruby -w # We started out with some code that averaged a ton of numbers in a # bunch of arrays. Once we finally lost our patience with the average # running time of the code, we decided to profile and optimize it # using RubyInline. class Array def average result = 0 self.each { |x| result += x } result / self.size.to_f end end max_loop = (ARGV.shift || 5).to_i max_size = (ARGV.shift || 100_000).to_i a = (1..max_size).to_a 1.upto(max_loop) do avg = a.average $stderr.print "." end $stderr.puts "" # The first step to profiling is to get a simple run of the code using # 'time' and a large dataset. This is because a profile run should # only be used for figuring out where your bottlenecks are, but the # runtime of a profile run should be considered invalid. This is # because set_trace_func, the main mechanism used by profile is a very # costly function. # & time ruby ./example1.rb 5 100000 # ..... # # real 0m4.580s # user 0m3.310s # sys 0m0.090s # (user+sys = 3.400s) # This gives us a tangible goal, to reduce the runtime of 4.58 seconds # as much as possible. The next step is to run with a smaller dataset # (because profiling is VERY SLOW) while including the profile module. # & ruby -rprofile ./example1.rb 3 10000 # ... # % cumulative self self total # time seconds seconds calls ms/call ms/call name # 69.78 4.78 4.78 3 1593.33 2273.33 Array#each # 29.78 6.82 2.04 30000 0.07 0.07 Fixnum#+ # 0.15 6.83 0.01 3 3.33 2276.67 Array#average # 0.15 6.84 0.01 1 10.00 10.00 Range#each # 0.00 6.84 0.00 1 0.00 10.00 Enumerable.to_a # -- CUT ALL FOLLOWING LINES WHERE %time == 0.00 # This says that Array#each and Fixnum#+ are the only two things we # should focus on at all. The rest of the time is statistically # insignificant. So, since average itself is a rather uncomplicated # method, we decided to convert the entire method rather than just try # to speed up the math or the loop separately. See example2.rb for the # continuation of this example. RubyInline-3.12.2/tutorial/example2.rb0000555000004100000410000000721112202216036017610 0ustar www-datawww-data#!/usr/bin/ruby -w -I.. require 'inline' class Array inline do |builder| builder.c_raw " static VALUE average(int argc, VALUE *argv, VALUE self) { double result = 0; long i, len; VALUE *arr = RARRAY_PTR(self); len = RARRAY_LEN(self); for(i=0; i