RubyInline 3.5.0 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +1 -2
- data/Rakefile +118 -0
- data/inline.rb +70 -48
- data/test_inline.rb +86 -50
- metadata +6 -6
- data/Makefile +0 -41
- data/inline.gemspec +0 -38
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
*** 3.6.0 / 2005-11-30 (omg I suck: actual release: 2006-09-15)
|
2
|
+
|
3
|
+
+ 6 minor enhancements
|
4
|
+
+ C builder can now be used directly for other foreign language glue.
|
5
|
+
+ Pretty much all (c) functions are plain argument style, not argc/argv.
|
6
|
+
+ Added Nathaniel and Dan's patches for windows support.
|
7
|
+
+ Added VALUE as a default known type.
|
8
|
+
+ Improved testing under $DEBUG.
|
9
|
+
+ Deprecated $INLINE_FLAGS and $INLINE_LIBS are dead.
|
10
|
+
+ 3 bug fixes
|
11
|
+
+ Fixed a number of issues wrt testing.
|
12
|
+
+ Cleaned up and cached certain calculations.
|
13
|
+
+ Some windows compiler fixes went in, but MS compiler is a PITA still.
|
14
|
+
|
1
15
|
*** 3.5.0 / 2005-10-15
|
2
16
|
|
3
17
|
+ 4 minor enhancements
|
data/Manifest.txt
CHANGED
data/Rakefile
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/contrib/sshpublisher'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
require 'rake/testtask'
|
8
|
+
require 'rbconfig'
|
9
|
+
|
10
|
+
PREFIX = ENV['PREFIX'] || Config::CONFIG['prefix']
|
11
|
+
RUBYLIB = Config::CONFIG['sitelibdir']
|
12
|
+
|
13
|
+
task :default => :test
|
14
|
+
|
15
|
+
task :test do
|
16
|
+
ruby %(-I. -w ./test_inline.rb)
|
17
|
+
end
|
18
|
+
|
19
|
+
task :examples do
|
20
|
+
%w(example.rb example2.rb tutorial/example1.rb tutorial/example2.rb).each do |e|
|
21
|
+
rm_rf '~/.ruby_inline'
|
22
|
+
ruby "-I. -w #{e}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
task :bench do
|
27
|
+
verbose(false) do
|
28
|
+
puts "Running native"
|
29
|
+
ruby "-I. ./example.rb 3"
|
30
|
+
puts "Running primer - preloads the compiler and stuff"
|
31
|
+
rm_rf '~/.ruby_inline'
|
32
|
+
ruby "-I. ./example.rb 0"
|
33
|
+
puts "With full builds"
|
34
|
+
(0..2).each do |i|
|
35
|
+
rm_rf '~/.ruby_inline'
|
36
|
+
ruby "-I. ./example.rb #{i}"
|
37
|
+
end
|
38
|
+
puts "Without builds"
|
39
|
+
(0..2).each do |i|
|
40
|
+
ruby "-I. ./example.rb #{i}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'Generate RDoc'
|
46
|
+
Rake::RDocTask.new :rdoc do |rd|
|
47
|
+
rd.rdoc_dir = 'doc'
|
48
|
+
rd.rdoc_files.add 'inline.rb', 'inline_package', 'README.txt', 'History.txt'
|
49
|
+
rd.main = 'README.txt'
|
50
|
+
rd.options << '-t RubyInline RDoc'
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'Upload RDoc to RubyForge'
|
54
|
+
task :upload => :rdoc do
|
55
|
+
config = YAML.load(File.read(File.expand_path("~/.rubyforge/config.yml")))
|
56
|
+
user = "#{config["username"]}@rubyforge.org"
|
57
|
+
project = '/var/www/gforge-projects/rubyinline'
|
58
|
+
local_dir = 'doc'
|
59
|
+
pub = Rake::SshDirPublisher.new user, project, local_dir
|
60
|
+
pub.upload
|
61
|
+
end
|
62
|
+
|
63
|
+
require 'rubygems'
|
64
|
+
require './inline.rb'
|
65
|
+
|
66
|
+
spec = Gem::Specification.new do |s|
|
67
|
+
|
68
|
+
s.name = 'RubyInline'
|
69
|
+
s.version = Inline::VERSION
|
70
|
+
s.summary = "Multi-language extension coding within ruby."
|
71
|
+
|
72
|
+
paragraphs = File.read("README.txt").split(/\n\n+/)
|
73
|
+
s.description = paragraphs[3]
|
74
|
+
puts s.description
|
75
|
+
|
76
|
+
s.requirements << "A POSIX environment and a compiler for your language."
|
77
|
+
s.files = IO.readlines("Manifest.txt").map {|f| f.chomp }
|
78
|
+
|
79
|
+
s.bindir = "."
|
80
|
+
s.executables = ['inline_package']
|
81
|
+
puts "Executables = #{s.executables.join(", ")}"
|
82
|
+
|
83
|
+
s.require_path = '.'
|
84
|
+
s.autorequire = 'inline'
|
85
|
+
|
86
|
+
s.has_rdoc = false # I SUCK - TODO
|
87
|
+
s.test_suite_file = "test_inline.rb"
|
88
|
+
|
89
|
+
s.author = "Ryan Davis"
|
90
|
+
s.email = "ryand-ruby@zenspider.com"
|
91
|
+
s.homepage = "http://www.zenspider.com/ZSS/Products/RubyInline/"
|
92
|
+
s.rubyforge_project = "rubyinline"
|
93
|
+
end
|
94
|
+
|
95
|
+
if $0 == __FILE__
|
96
|
+
Gem.manage_gems
|
97
|
+
Gem::Builder.new(spec).build
|
98
|
+
end
|
99
|
+
|
100
|
+
desc 'Build Gem'
|
101
|
+
Rake::GemPackageTask.new spec do |pkg|
|
102
|
+
pkg.need_tar = true
|
103
|
+
end
|
104
|
+
|
105
|
+
task :install do
|
106
|
+
install 'inline.rb', RUBYLIB, :mode => 0444
|
107
|
+
install 'inline_package', File.join(PREFIX, 'bin'), :mode => 0555
|
108
|
+
end
|
109
|
+
|
110
|
+
task :uninstall do
|
111
|
+
rm File.join(RUBYLIB, 'inline.rb')
|
112
|
+
rm File.join(PREFIX, 'bin', 'inline_package')
|
113
|
+
end
|
114
|
+
|
115
|
+
task :clean => [ :clobber_rdoc, :clobber_package ] do
|
116
|
+
rm Dir["*~"]
|
117
|
+
rm_rf %w(~/.ruby_inline)
|
118
|
+
end
|
data/inline.rb
CHANGED
@@ -51,7 +51,12 @@ class CompilationError < RuntimeError; end
|
|
51
51
|
# the current namespace.
|
52
52
|
|
53
53
|
module Inline
|
54
|
-
VERSION = '3.
|
54
|
+
VERSION = '3.6.0'
|
55
|
+
|
56
|
+
WINDOZE = /win32/ =~ RUBY_PLATFORM
|
57
|
+
DEV_NULL = (WINDOZE ? 'nul' : '/dev/null')
|
58
|
+
RAKE = (WINDOZE ? 'rake.cmd' : 'rake')
|
59
|
+
GEM = (WINDOZE ? 'gem.cmd' : 'gem')
|
55
60
|
|
56
61
|
$stderr.puts "RubyInline v #{VERSION}" if $DEBUG
|
57
62
|
|
@@ -59,8 +64,14 @@ module Inline
|
|
59
64
|
|
60
65
|
def self.rootdir
|
61
66
|
env = ENV['INLINEDIR'] || ENV['HOME']
|
67
|
+
|
68
|
+
if env.nil? then
|
69
|
+
$stderr.puts "Define INLINEDIR or HOME in your environment and try again"
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
|
62
73
|
unless defined? @@rootdir and env == @@rootdir and test ?d, @@rootdir then
|
63
|
-
rootdir =
|
74
|
+
rootdir = env
|
64
75
|
Dir.mkdir rootdir, 0700 unless test ?d, rootdir
|
65
76
|
Dir.assert_secure rootdir
|
66
77
|
@@rootdir = rootdir
|
@@ -91,7 +102,7 @@ module Inline
|
|
91
102
|
|
92
103
|
protected unless $TESTING
|
93
104
|
|
94
|
-
MAGIC_ARITY_THRESHOLD =
|
105
|
+
MAGIC_ARITY_THRESHOLD = 15
|
95
106
|
MAGIC_ARITY = -1
|
96
107
|
|
97
108
|
@@type_map = {
|
@@ -103,6 +114,7 @@ module Inline
|
|
103
114
|
'unsigned int' => [ 'NUM2UINT', 'UINT2NUM' ],
|
104
115
|
'unsigned long' => [ 'NUM2UINT', 'UINT2NUM' ],
|
105
116
|
'unsigned' => [ 'NUM2UINT', 'UINT2NUM' ],
|
117
|
+
'VALUE' => [ '', '' ],
|
106
118
|
# Can't do these converters because they conflict with the above:
|
107
119
|
# ID2SYM(x), SYM2ID(x), NUM2DBL(x), FIX2UINT(x)
|
108
120
|
}
|
@@ -135,9 +147,11 @@ module Inline
|
|
135
147
|
# clean and collapse whitespace
|
136
148
|
sig.gsub!(/\s+/, ' ')
|
137
149
|
|
138
|
-
|
150
|
+
unless defined? @types then
|
151
|
+
@types = 'void|VALUE|' + @@type_map.keys.map{|x| Regexp.escape(x)}.join('|')
|
152
|
+
end
|
139
153
|
|
140
|
-
if /(#{types})\s*(\w+)\s*\(([^)]*)\)/ =~ sig then
|
154
|
+
if /(#{@types})\s*(\w+)\s*\(([^)]*)\)/ =~ sig then
|
141
155
|
return_type, function_name, arg_string = $1, $2, $3
|
142
156
|
args = []
|
143
157
|
arg_string.split(',').each do |arg|
|
@@ -145,8 +159,7 @@ module Inline
|
|
145
159
|
# helps normalize into 'char * varname' form
|
146
160
|
arg = arg.gsub(/\s*\*\s*/, ' * ').strip
|
147
161
|
|
148
|
-
|
149
|
-
if /(((#{types})\s*\*?)+)\s+(\w+)\s*$/ =~ arg then
|
162
|
+
if /(((#{@types})\s*\*?)+)\s+(\w+)\s*$/ =~ arg then
|
150
163
|
args.push([$4, $1])
|
151
164
|
elsif arg != "void" then
|
152
165
|
$stderr.puts "WARNING: '#{arg}' not understood"
|
@@ -154,7 +167,7 @@ module Inline
|
|
154
167
|
end
|
155
168
|
|
156
169
|
arity = args.size
|
157
|
-
arity =
|
170
|
+
arity = MAGIC_ARITY if raw
|
158
171
|
|
159
172
|
return {
|
160
173
|
'return' => return_type,
|
@@ -168,10 +181,7 @@ module Inline
|
|
168
181
|
end # def parse_signature
|
169
182
|
|
170
183
|
def generate(src, options={})
|
171
|
-
|
172
|
-
if not Hash === options then
|
173
|
-
options = {:expand_types=>options}
|
174
|
-
end
|
184
|
+
options = {:expand_types=>options} unless Hash === options
|
175
185
|
|
176
186
|
expand_types = options[:expand_types]
|
177
187
|
singleton = options[:singleton]
|
@@ -182,28 +192,21 @@ module Inline
|
|
182
192
|
return_type = signature['return']
|
183
193
|
arity = signature['arity']
|
184
194
|
|
195
|
+
raise ArgumentError, "too many arguments" if arity > MAGIC_ARITY_THRESHOLD
|
196
|
+
|
185
197
|
if expand_types then
|
186
198
|
prefix = "static VALUE #{function_name}("
|
187
199
|
if arity == MAGIC_ARITY then
|
188
200
|
prefix += "int argc, VALUE *argv, VALUE self"
|
189
201
|
else
|
190
202
|
prefix += "VALUE self"
|
191
|
-
|
192
|
-
prefix += ", VALUE _#{arg}"
|
193
|
-
end
|
203
|
+
prefix += signature['args'].map { |arg, type| ", VALUE _#{arg}"}.join
|
194
204
|
end
|
195
205
|
prefix += ") {\n"
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
count += 1
|
201
|
-
end
|
202
|
-
else
|
203
|
-
signature['args'].each do |arg, type|
|
204
|
-
prefix += " #{type} #{arg} = #{ruby2c(type)}(_#{arg});\n"
|
205
|
-
end
|
206
|
-
end
|
206
|
+
prefix += signature['args'].map { |arg, type|
|
207
|
+
" #{type} #{arg} = #{ruby2c(type)}(_#{arg});\n"
|
208
|
+
}.join
|
209
|
+
|
207
210
|
# replace the function signature (hopefully) with new sig (prefix)
|
208
211
|
result.sub!(/[^;\/\"\>]+#{function_name}\s*\([^\{]+\{/, "\n" + prefix)
|
209
212
|
result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
|
@@ -230,7 +233,7 @@ module Inline
|
|
230
233
|
end
|
231
234
|
|
232
235
|
file, line = caller[1].split(/:/)
|
233
|
-
result = "# line #{line.to_i + delta} \"#{file}\"\n" + result unless $DEBUG
|
236
|
+
result = "# line #{line.to_i + delta} \"#{file}\"\n" + result unless $DEBUG and not $TESTING
|
234
237
|
|
235
238
|
@src << result
|
236
239
|
@sig[function_name] = [arity,singleton]
|
@@ -242,7 +245,7 @@ module Inline
|
|
242
245
|
unless defined? @module_name then
|
243
246
|
module_name = @mod.name.gsub('::','__')
|
244
247
|
md5 = Digest::MD5.new
|
245
|
-
@sig.keys.sort_by{|x| x.to_s}.each { |m| md5 << m.to_s }
|
248
|
+
@sig.keys.sort_by { |x| x.to_s }.each { |m| md5 << m.to_s }
|
246
249
|
@module_name = "Inline_#{module_name}_#{md5.to_s[0,4]}"
|
247
250
|
end
|
248
251
|
@module_name
|
@@ -264,11 +267,11 @@ module Inline
|
|
264
267
|
raise ArgumentError, "Class/Module arg is required" unless Module === mod
|
265
268
|
# new (but not on some 1.8s) -> inline -> real_caller|eval
|
266
269
|
stack = caller
|
267
|
-
meth = stack.shift until meth =~ /in .(inline|test_)/ or stack.empty?
|
270
|
+
meth = stack.shift until meth =~ /in .(inline|test_|setup)/ or stack.empty?
|
268
271
|
raise "Couldn't discover caller" if stack.empty?
|
269
272
|
real_caller = stack.first
|
270
273
|
real_caller = stack[3] if real_caller =~ /\(eval\)/
|
271
|
-
@real_caller = real_caller.split(/:/).
|
274
|
+
@real_caller = real_caller.split(/:/)[0..-2].join(':')
|
272
275
|
@rb_file = File.expand_path(@real_caller)
|
273
276
|
|
274
277
|
@mod = mod
|
@@ -308,7 +311,6 @@ module Inline
|
|
308
311
|
def build
|
309
312
|
so_name = self.so_name
|
310
313
|
so_exists = File.file? so_name
|
311
|
-
|
312
314
|
unless so_exists and File.mtime(rb_file) < File.mtime(so_name)
|
313
315
|
|
314
316
|
src_name = "#{Inline.directory}/#{module_name}.c"
|
@@ -323,12 +325,15 @@ module Inline
|
|
323
325
|
io.puts "#ifdef __cplusplus"
|
324
326
|
io.puts "extern \"C\" {"
|
325
327
|
io.puts "#endif"
|
328
|
+
io.puts " __declspec(dllexport)" if WINDOZE
|
326
329
|
io.puts " void Init_#{module_name}() {"
|
327
330
|
io.puts " VALUE c = rb_cObject;"
|
331
|
+
|
328
332
|
# TODO: use rb_class2path
|
329
|
-
@mod.name.split("::").
|
330
|
-
|
331
|
-
|
333
|
+
io.puts @mod.name.split("::").map { |n|
|
334
|
+
" c = rb_const_get_at(c,rb_intern(\"#{n}\"));"
|
335
|
+
}.join("\n")
|
336
|
+
|
332
337
|
@sig.keys.sort.each do |name|
|
333
338
|
arity, singleton = @sig[name]
|
334
339
|
if singleton then
|
@@ -377,28 +382,40 @@ module Inline
|
|
377
382
|
end
|
378
383
|
|
379
384
|
flags = @flags.join(' ')
|
380
|
-
flags += " #{$INLINE_FLAGS}" if defined? $INLINE_FLAGS# DEPRECATE
|
381
385
|
libs = @libs.join(' ')
|
382
|
-
libs += " #{$INLINE_LIBS}" if defined? $INLINE_LIBS # DEPRECATE
|
383
386
|
|
384
|
-
|
387
|
+
cmd = "#{Config::CONFIG['LDSHARED']} #{flags} #{Config::CONFIG['CFLAGS']} -I #{hdrdir} -o \"#{so_name}\" \"#{File.expand_path(src_name)}\" #{libs}"
|
385
388
|
|
386
389
|
case RUBY_PLATFORM
|
387
390
|
when /mswin32/ then
|
388
|
-
|
391
|
+
cmd += " -link /LIBPATH:\"#{Config::CONFIG['libdir']}\" /DEFAULTLIB:\"#{Config::CONFIG['LIBRUBY']}\" /INCREMENTAL:no /EXPORT:Init_#{module_name}"
|
389
392
|
when /i386-cygwin/ then
|
390
393
|
cmd += ' -L/usr/local/lib -lruby.dll'
|
391
394
|
end
|
392
395
|
|
393
|
-
cmd += " 2>
|
396
|
+
cmd += " 2> #{DEV_NULL}" if $TESTING and not $DEBUG
|
394
397
|
|
395
398
|
$stderr.puts "Building #{so_name} with '#{cmd}'" if $DEBUG
|
396
|
-
`#{cmd}`
|
399
|
+
result = `#{cmd}`
|
400
|
+
$stderr.puts "Output:\n#{result}" if $DEBUG
|
397
401
|
if $? != 0 then
|
398
402
|
bad_src_name = src_name + ".bad"
|
399
403
|
File.rename src_name, bad_src_name
|
400
404
|
raise CompilationError, "error executing #{cmd}: #{$?}\nRenamed #{src_name} to #{bad_src_name}"
|
401
405
|
end
|
406
|
+
|
407
|
+
if WINDOZE then
|
408
|
+
Dir.chdir self.directory do
|
409
|
+
cmd = "mt /manifest lib.so.manifest /outputresource:so.dll;#2"
|
410
|
+
$stderr.puts "Embedding manifest with '#{cmd}'" if $DEBUG
|
411
|
+
result = `#{cmd}`
|
412
|
+
$stderr.puts "Output:\n#{result}" if $DEBUG
|
413
|
+
if $? != 0 then
|
414
|
+
raise CompilationError, "error executing #{cmd}: #{$?}"
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
402
419
|
$stderr.puts "Built successfully" if $DEBUG
|
403
420
|
end
|
404
421
|
|
@@ -536,14 +553,19 @@ module Inline
|
|
536
553
|
end
|
537
554
|
|
538
555
|
def build_gem
|
539
|
-
STDERR.puts "==> Running rake" unless $TESTING
|
540
|
-
|
541
|
-
cmd = "rake package"
|
542
|
-
cmd += "> /dev/null 2> /dev/null" if $TESTING
|
543
|
-
system cmd
|
556
|
+
STDERR.puts "==> Running rake" unless $TESTING or $DEBUG
|
544
557
|
|
545
|
-
|
546
|
-
|
558
|
+
cmd = "#{RAKE} package"
|
559
|
+
cmd += "> #{DEV_NULL} 2> #{DEV_NULL}" if $TESTING unless $DEBUG
|
560
|
+
|
561
|
+
if system cmd then
|
562
|
+
unless $TESTING then
|
563
|
+
STDERR.puts
|
564
|
+
STDERR.puts "Ok, you now have a gem in ./pkg, enjoy!"
|
565
|
+
end
|
566
|
+
else
|
567
|
+
STDERR.puts "Calling rake to build the gem failed." unless $TESTING
|
568
|
+
end
|
547
569
|
end
|
548
570
|
|
549
571
|
def gem_libs
|
@@ -643,7 +665,7 @@ class Dir
|
|
643
665
|
if $TESTING then
|
644
666
|
raise SecurityError, "Directory #{path} is insecure"
|
645
667
|
else
|
646
|
-
$stderr.puts "#{path} is insecure (#{
|
668
|
+
$stderr.puts "#{path} is insecure (#{'%o' % mode}). It may not be group or world writable. Exiting."
|
647
669
|
exit 1
|
648
670
|
end
|
649
671
|
end
|
data/test_inline.rb
CHANGED
@@ -1,25 +1,38 @@
|
|
1
|
-
#!/usr/local/bin/ruby -w
|
2
|
-
|
3
1
|
$TESTING = true
|
4
2
|
|
3
|
+
$0 = __FILE__ if $0 == "-e" # for autotest style execution
|
4
|
+
|
5
5
|
require 'inline'
|
6
6
|
require 'tempfile'
|
7
|
+
require 'tmpdir'
|
7
8
|
require 'test/unit'
|
8
9
|
|
9
10
|
File.umask(0)
|
10
11
|
|
12
|
+
module Foo
|
13
|
+
class Bar
|
14
|
+
inline do |builder|
|
15
|
+
builder.c <<-EOC
|
16
|
+
int arity6(int u, int v, int w, int x, int y, char * z) { return x + y + strlen(z); }
|
17
|
+
EOC
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
11
22
|
class InlineTestCase < Test::Unit::TestCase
|
12
23
|
|
13
24
|
def setup
|
14
25
|
super
|
15
|
-
@rootdir = "
|
16
|
-
Dir.mkdir @rootdir, 0700
|
26
|
+
@rootdir = File.join(Dir.tmpdir, "test_inline.#{$$}")
|
27
|
+
Dir.mkdir @rootdir, 0700 unless test ?d, @rootdir
|
17
28
|
ENV['INLINEDIR'] = @rootdir
|
18
29
|
end
|
19
30
|
|
20
31
|
def teardown
|
21
|
-
|
22
|
-
|
32
|
+
unless $DEBUG then
|
33
|
+
FileUtils.rm_rf @rootdir
|
34
|
+
ENV.delete 'INLINEDIR'
|
35
|
+
end
|
23
36
|
end
|
24
37
|
|
25
38
|
def test_stupid
|
@@ -29,7 +42,6 @@ class InlineTestCase < Test::Unit::TestCase
|
|
29
42
|
end
|
30
43
|
|
31
44
|
class TestDir < InlineTestCase
|
32
|
-
|
33
45
|
def setup
|
34
46
|
super
|
35
47
|
@count = 1
|
@@ -41,11 +53,11 @@ class TestDir < InlineTestCase
|
|
41
53
|
Dir.mkdir path, perms unless perms.nil?
|
42
54
|
if should_pass then
|
43
55
|
assert_nothing_raised do
|
44
|
-
|
56
|
+
Dir.assert_secure path
|
45
57
|
end
|
46
58
|
else
|
47
59
|
assert_raises(perms.nil? ? Errno::ENOENT : SecurityError) do
|
48
|
-
|
60
|
+
Dir.assert_secure path
|
49
61
|
end
|
50
62
|
end
|
51
63
|
end
|
@@ -60,7 +72,7 @@ class TestDir < InlineTestCase
|
|
60
72
|
# missing
|
61
73
|
util_assert_secure nil, false
|
62
74
|
end
|
63
|
-
end
|
75
|
+
end unless Inline::WINDOZE
|
64
76
|
|
65
77
|
class TestInline < InlineTestCase
|
66
78
|
|
@@ -78,6 +90,12 @@ end
|
|
78
90
|
class TestInline
|
79
91
|
class TestC < InlineTestCase
|
80
92
|
|
93
|
+
def setup
|
94
|
+
super
|
95
|
+
@builder = Inline::C.new(self.class)
|
96
|
+
end
|
97
|
+
|
98
|
+
|
81
99
|
# quick hack to make tests more readable,
|
82
100
|
# does nothing I wouldn't otherwise do...
|
83
101
|
def inline(lang=:C)
|
@@ -104,6 +122,7 @@ class TestC < InlineTestCase
|
|
104
122
|
assert_equal 'NUM2UINT', x.ruby2c("unsigned int")
|
105
123
|
assert_equal 'NUM2UINT', x.ruby2c("unsigned long")
|
106
124
|
assert_equal 'NUM2UINT', x.ruby2c("unsigned")
|
125
|
+
assert_equal '', x.ruby2c("VALUE")
|
107
126
|
|
108
127
|
assert_raises ArgumentError do
|
109
128
|
x.ruby2c('blah')
|
@@ -119,6 +138,7 @@ class TestC < InlineTestCase
|
|
119
138
|
assert_equal 'UINT2NUM', x.c2ruby("unsigned int")
|
120
139
|
assert_equal 'UINT2NUM', x.c2ruby("unsigned long")
|
121
140
|
assert_equal 'UINT2NUM', x.c2ruby("unsigned")
|
141
|
+
assert_equal '', x.c2ruby("VALUE")
|
122
142
|
|
123
143
|
assert_raises ArgumentError do
|
124
144
|
x.c2ruby('blah')
|
@@ -127,15 +147,14 @@ class TestC < InlineTestCase
|
|
127
147
|
|
128
148
|
def util_module_name(*signatures)
|
129
149
|
md5 = Digest::MD5.new
|
130
|
-
builder = Inline::C.new(self.class)
|
131
150
|
|
132
151
|
signatures.each do |signature|
|
133
|
-
builder.sig[signature] = [nil, 0]
|
152
|
+
@builder.sig[signature] = [nil, 0]
|
134
153
|
md5 << signature.to_s
|
135
154
|
end
|
136
155
|
|
137
156
|
assert_equal("Inline_TestInline__TestC_#{md5.to_s[0,4]}",
|
138
|
-
builder.module_name)
|
157
|
+
@builder.module_name)
|
139
158
|
end
|
140
159
|
|
141
160
|
def test_module_name_0_methods
|
@@ -155,12 +174,10 @@ class TestC < InlineTestCase
|
|
155
174
|
end
|
156
175
|
|
157
176
|
def util_parse_signature(src, expected, t=nil, a=nil, b=nil)
|
158
|
-
|
159
177
|
result = nil
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
178
|
+
|
179
|
+
@builder.add_type_converter t, a, b unless t.nil?
|
180
|
+
result = @builder.parse_signature(src)
|
164
181
|
|
165
182
|
assert_equal(expected, result)
|
166
183
|
end
|
@@ -243,10 +260,7 @@ class TestC < InlineTestCase
|
|
243
260
|
end
|
244
261
|
|
245
262
|
def util_generate(src, expected, expand_types=true)
|
246
|
-
result =
|
247
|
-
inline do |builder|
|
248
|
-
result = builder.generate src, expand_types
|
249
|
-
end
|
263
|
+
result = @builder.generate src, expand_types
|
250
264
|
result.gsub!(/\# line \d+/, '# line N')
|
251
265
|
expected = "# line N \"#{$0}\"\n" + expected
|
252
266
|
assert_equal(expected, result)
|
@@ -355,16 +369,15 @@ return INT2FIX(42)}"
|
|
355
369
|
util_generate_raw(src, expected)
|
356
370
|
end
|
357
371
|
|
358
|
-
def
|
359
|
-
src = "int
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
int y = FIX2INT(argv[1]);
|
364
|
-
int z = FIX2INT(argv[2]);
|
365
|
-
blah; return INT2FIX(x+y+z);}"
|
372
|
+
def test_generate_arity_too_many
|
373
|
+
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) {
|
374
|
+
int q = v + w;
|
375
|
+
return q+x+y+z;
|
376
|
+
}"
|
366
377
|
|
367
|
-
|
378
|
+
assert_raise(ArgumentError) do
|
379
|
+
@builder.generate src, true
|
380
|
+
end
|
368
381
|
end
|
369
382
|
|
370
383
|
def test_generate_comments
|
@@ -456,35 +469,28 @@ puts(s); return rb_str_new2(s)}"
|
|
456
469
|
end
|
457
470
|
|
458
471
|
def test_c
|
459
|
-
|
460
|
-
inline(:C) do |b|
|
461
|
-
builder = b
|
462
|
-
result = builder.c "int add(int a, int b) { return a + b; }"
|
463
|
-
end
|
472
|
+
result = @builder.c "int add(int a, int b) { return a + b; }"
|
464
473
|
|
465
474
|
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); }"
|
466
475
|
|
467
476
|
result.gsub!(/\# line \d+/, '# line N')
|
468
477
|
|
469
478
|
assert_equal expected, result
|
470
|
-
assert_equal [expected], builder.src
|
479
|
+
assert_equal [expected], @builder.src
|
471
480
|
end
|
472
481
|
|
473
482
|
def test_c_raw
|
474
483
|
src = "static VALUE answer_raw(int argc, VALUE *argv, VALUE self) { return INT2NUM(42); }"
|
475
|
-
|
476
|
-
inline(:C) do |b|
|
477
|
-
builder = b
|
478
|
-
result = builder.c_raw src.dup
|
479
|
-
end
|
484
|
+
result = @builder.c_raw src.dup
|
480
485
|
|
481
486
|
result.gsub!(/\# line \d+/, '# line N')
|
482
487
|
expected = "# line N \"#{$0}\"\n" + src
|
483
488
|
|
484
489
|
assert_equal expected, result
|
485
|
-
assert_equal [expected], builder.src
|
490
|
+
assert_equal [expected], @builder.src
|
486
491
|
end
|
487
492
|
|
493
|
+
# TODO: fix ?
|
488
494
|
def util_simple_code(klassname, c_src)
|
489
495
|
result = "
|
490
496
|
require 'inline'
|
@@ -502,8 +508,7 @@ puts(s); return rb_str_new2(s)}"
|
|
502
508
|
def util_test_build(src)
|
503
509
|
tempfile = Tempfile.new("util_test_build")
|
504
510
|
tempfile.write src
|
505
|
-
tempfile.
|
506
|
-
tempfile.rewind
|
511
|
+
tempfile.close
|
507
512
|
rb_file = tempfile.path + ".rb"
|
508
513
|
File.rename tempfile.path, rb_file
|
509
514
|
begin
|
@@ -592,6 +597,26 @@ class TestModule < InlineTestCase
|
|
592
597
|
`rm "#{tempfile.path}.rb"`
|
593
598
|
end
|
594
599
|
|
600
|
+
def test_argument_check_good
|
601
|
+
fb = Foo::Bar.new
|
602
|
+
assert_equal 13, fb.arity6(1, 2, 3, 4, 5, "blah")
|
603
|
+
end
|
604
|
+
|
605
|
+
def test_argument_check_fewer
|
606
|
+
fb = Foo::Bar.new
|
607
|
+
|
608
|
+
assert_raise(ArgumentError) do
|
609
|
+
assert_equal 13, fb.arity6(1, 2, 3)
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
def test_argument_check_more
|
614
|
+
fb = Foo::Bar.new
|
615
|
+
assert_raise ArgumentError do
|
616
|
+
assert_equal 13, fb.arity6(1, 2, 3, 4, 5, "blah", :extra)
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
595
620
|
def test_inline
|
596
621
|
self.class.inline(:C) do |builder|
|
597
622
|
builder.c "int add(int a, int b) { return a + b; }"
|
@@ -611,13 +636,14 @@ class TestInlinePackager < InlineTestCase
|
|
611
636
|
|
612
637
|
def setup
|
613
638
|
super
|
639
|
+
|
614
640
|
@name = "Packager Test"
|
615
641
|
@version = "1.0.0"
|
616
642
|
@summary = "This is a Packager test gem"
|
617
643
|
@packager = Inline::Packager.new @name, @version, @summary
|
618
644
|
|
619
645
|
@package_dir = @rootdir + "_package"
|
620
|
-
Dir.mkdir @package_dir, 0700
|
646
|
+
Dir.mkdir @package_dir, 0700 unless test ?d, @package_dir
|
621
647
|
@orig_dir = Dir.pwd
|
622
648
|
Dir.chdir @package_dir
|
623
649
|
|
@@ -656,7 +682,7 @@ class TestInlinePackager < InlineTestCase
|
|
656
682
|
built_lib = "Inline_Test.#{@ext}"
|
657
683
|
dir = "#{@rootdir}/.ruby_inline"
|
658
684
|
|
659
|
-
Dir.mkdir dir, 0700
|
685
|
+
Dir.mkdir dir, 0700 unless test ?d, dir
|
660
686
|
Dir.chdir dir do
|
661
687
|
FileUtils.touch built_lib
|
662
688
|
end
|
@@ -670,6 +696,7 @@ class TestInlinePackager < InlineTestCase
|
|
670
696
|
end
|
671
697
|
|
672
698
|
def test_generate_rakefile_has_rakefile
|
699
|
+
FileUtils.rm 'Rakefile' if test ?f, 'Rakefile' and $DEBUG
|
673
700
|
FileUtils.touch 'Rakefile'
|
674
701
|
|
675
702
|
@packager.generate_rakefile
|
@@ -678,23 +705,32 @@ class TestInlinePackager < InlineTestCase
|
|
678
705
|
end
|
679
706
|
|
680
707
|
def test_generate_rakefile_no_rakefile
|
708
|
+
FileUtils.rm 'Rakefile' if test ?f, 'Rakefile' and $DEBUG
|
709
|
+
FileUtils.rm_r 'lib' if test ?d, 'lib' and $DEBUG
|
710
|
+
|
681
711
|
@packager.generate_rakefile
|
682
712
|
|
683
713
|
assert_equal util_generate_rakefile, File.read('Rakefile')
|
684
714
|
end
|
685
715
|
|
686
716
|
def test_build_gem
|
717
|
+
# test_copy_libs
|
718
|
+
pwd = Dir.pwd
|
719
|
+
|
687
720
|
File.open 'Rakefile', 'w' do |fp|
|
688
|
-
|
721
|
+
src = util_generate_rakefile
|
722
|
+
fp.puts src
|
689
723
|
end
|
690
724
|
|
691
725
|
@packager.build_gem
|
726
|
+
|
692
727
|
package_name = "pkg/#{@name}-#{@version}.gem"
|
693
|
-
|
694
|
-
|
728
|
+
assert File.exists?(package_name), "File #{package_name} must exist"
|
729
|
+
assert system("#{Inline::GEM} check #{package_name}"), "gem check must pass"
|
695
730
|
end
|
696
731
|
|
697
732
|
def test_gem_libs
|
733
|
+
system "rm lib/inline/*" if $DEBUG # hacky
|
698
734
|
@packager.libs_copied = true
|
699
735
|
expected = ["lib/blah.rb", "lib/inline/Inline_Test.#{@ext}"]
|
700
736
|
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
!ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
3
|
specification_version: 1
|
4
4
|
name: RubyInline
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 3.
|
7
|
-
date:
|
6
|
+
version: 3.6.0
|
7
|
+
date: 2006-09-15 00:00:00 -07:00
|
8
8
|
summary: Multi-language extension coding within ruby.
|
9
9
|
require_paths:
|
10
10
|
- .
|
@@ -25,18 +25,18 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Ryan Davis
|
30
31
|
files:
|
31
32
|
- History.txt
|
32
|
-
- Makefile
|
33
33
|
- Manifest.txt
|
34
34
|
- README.txt
|
35
|
+
- Rakefile
|
35
36
|
- demo/fastmath.rb
|
36
37
|
- demo/hello.rb
|
37
38
|
- example.rb
|
38
39
|
- example2.rb
|
39
|
-
- inline.gemspec
|
40
40
|
- inline.rb
|
41
41
|
- inline_package
|
42
42
|
- test_inline.rb
|
data/Makefile
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
RUBY?=/usr/local/bin/ruby
|
2
|
-
RDOC?=rdoc
|
3
|
-
RUBYLIB=$(shell $(RUBY) -rrbconfig -e 'include Config; print CONFIG["sitelibdir"]')
|
4
|
-
PREFIX?=/usr/local
|
5
|
-
|
6
|
-
test:
|
7
|
-
$(RUBY) -I. -w ./test_inline.rb
|
8
|
-
|
9
|
-
examples:
|
10
|
-
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./example.rb
|
11
|
-
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./example2.rb
|
12
|
-
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./tutorial/example1.rb
|
13
|
-
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./tutorial/example2.rb
|
14
|
-
|
15
|
-
docs:
|
16
|
-
$(RDOC) --main inline.rb
|
17
|
-
|
18
|
-
bench:
|
19
|
-
@echo "Running native"
|
20
|
-
@$(RUBY) -I. ./example.rb 3 2> /dev/null
|
21
|
-
@echo "Running primer - preloads the compiler and stuff"
|
22
|
-
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 0 2>&1 > /dev/null
|
23
|
-
@echo "With full builds"
|
24
|
-
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 0 2> /dev/null
|
25
|
-
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 1 2> /dev/null
|
26
|
-
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 2 2> /dev/null
|
27
|
-
@echo "Without builds"
|
28
|
-
@$(RUBY) -I. ./example.rb 0 2> /dev/null
|
29
|
-
@$(RUBY) -I. ./example.rb 1 2> /dev/null
|
30
|
-
@$(RUBY) -I. ./example.rb 2 2> /dev/null
|
31
|
-
|
32
|
-
install:
|
33
|
-
install -m 0444 inline.rb $(RUBYLIB)
|
34
|
-
install -m 0555 inline_package $(PREFIX)/bin
|
35
|
-
|
36
|
-
uninstall:
|
37
|
-
rm -f $(RUBYLIB)/inline.rb
|
38
|
-
rm -f $(PREFIX)/bin/inline_package
|
39
|
-
|
40
|
-
clean:
|
41
|
-
rm -rf *~ doc ~/.ruby_inline
|
data/inline.gemspec
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'inline'
|
5
|
-
|
6
|
-
spec = Gem::Specification.new do |s|
|
7
|
-
|
8
|
-
s.name = 'RubyInline'
|
9
|
-
s.version = Inline::VERSION
|
10
|
-
s.summary = "Multi-language extension coding within ruby."
|
11
|
-
|
12
|
-
paragraphs = File.read("README.txt").split(/\n\n+/)
|
13
|
-
s.description = paragraphs[3]
|
14
|
-
puts s.description
|
15
|
-
|
16
|
-
s.requirements << "A POSIX environment and a compiler for your language."
|
17
|
-
s.files = IO.readlines("Manifest.txt").map {|f| f.chomp }
|
18
|
-
|
19
|
-
s.bindir = "."
|
20
|
-
s.executables = ['inline_package']
|
21
|
-
puts "Executables = #{s.executables.join(", ")}"
|
22
|
-
|
23
|
-
s.require_path = '.'
|
24
|
-
s.autorequire = 'inline'
|
25
|
-
|
26
|
-
s.has_rdoc = false # I SUCK - TODO
|
27
|
-
s.test_suite_file = "test_inline.rb"
|
28
|
-
|
29
|
-
s.author = "Ryan Davis"
|
30
|
-
s.email = "ryand-ruby@zenspider.com"
|
31
|
-
s.homepage = "http://www.zenspider.com/ZSS/Products/RubyInline/"
|
32
|
-
s.rubyforge_project = "rubyinline"
|
33
|
-
end
|
34
|
-
|
35
|
-
if $0 == __FILE__
|
36
|
-
Gem.manage_gems
|
37
|
-
Gem::Builder.new(spec).build
|
38
|
-
end
|