RubyInline 3.6.2 → 3.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,6 +1,20 @@
1
+ *** 3.6.3 / 2007-04-27
2
+
3
+ + 7 minor enhancements:
4
+ Added map_ruby_const and map_c_const to C builder.
5
+ Converted example.rb to a real benchmark setup.
6
+ Improved error messages.
7
+ Added options hash for all C builder methods.
8
+ Options hash can take optional :method_name param to have ruby name diff from c.
9
+ Converted to a more traditional setup. Now I can heckle!
10
+ Cleaned up ruby.h search.
11
+ + 2 bug fixes:
12
+ Added CCDLFLAGS. _Should_ pick up -fPIC on misconfigured 64 bit machines.
13
+ Broke up all warnings so progress report was cleaner.
14
+
1
15
  *** 3.6.2 / 2006-10-12
2
16
 
3
- + 2 bug fixes
17
+ + 2 bug fixes:
4
18
  + comment stripper much more sane to fix problems on certain linux distros
5
19
  + fixed a nit with older C compilers.
6
20
 
data/Manifest.txt CHANGED
@@ -2,12 +2,12 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
+ bin/inline_package
5
6
  demo/fastmath.rb
6
7
  demo/hello.rb
7
8
  example.rb
8
9
  example2.rb
9
- inline.rb
10
- inline_package
11
- test_inline.rb
10
+ lib/inline.rb
11
+ test/test_inline.rb
12
12
  tutorial/example1.rb
13
13
  tutorial/example2.rb
data/README.txt CHANGED
@@ -1,8 +1,7 @@
1
1
  ** Ruby Inline
2
2
 
3
- http://www.zenspider.com/ZSS/Products/RubyInline/
4
3
  http://rubyforge.org/projects/rubyinline/
5
- support@zenspider.com
4
+ http://www.zenspider.com/ZSS/Products/RubyInline/
6
5
 
7
6
  ** DESCRIPTION:
8
7
 
data/Rakefile CHANGED
@@ -3,44 +3,28 @@
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
5
 
6
- require './inline.rb'
6
+ require './lib/inline.rb'
7
7
 
8
8
  Hoe.new("RubyInline", Inline::VERSION) do |p|
9
9
  p.summary = "Multi-language extension coding within ruby."
10
10
  p.description = p.paragraphs_of("README.txt", 3).join
11
+ p.url = p.paragraphs_of("README.txt", 1).join
11
12
  p.changes = p.paragraphs_of("History.txt", 0..1).join
12
13
  p.clean_globs << File.expand_path("~/.ruby_inline")
13
14
 
14
15
  p.spec_extras[:requirements] = "A POSIX environment and a compiler for your language."
15
- p.spec_extras[:require_paths] = ["."]
16
-
17
- p.lib_files = %w(inline.rb)
18
- p.test_files = %w(test_inline.rb)
19
- p.bin_files = %w(inline_package)
20
16
  end
21
17
 
22
18
  task :examples do
23
19
  %w(example.rb example2.rb tutorial/example1.rb tutorial/example2.rb).each do |e|
24
20
  rm_rf '~/.ruby_inline'
25
- ruby "-I. -w #{e}"
21
+ ruby "-Ilib -w #{e}"
26
22
  end
27
23
  end
28
24
 
29
25
  task :bench do
30
26
  verbose(false) do
31
- puts "Running native"
32
- ruby "-I. ./example.rb 3"
33
- puts "Running primer - preloads the compiler and stuff"
34
- rm_rf '~/.ruby_inline'
35
- ruby "-I. ./example.rb 0"
36
- puts "With full builds"
37
- (0..2).each do |i|
38
- rm_rf '~/.ruby_inline'
39
- ruby "-I. ./example.rb #{i}"
40
- end
41
- puts "Without builds"
42
- (0..2).each do |i|
43
- ruby "-I. ./example.rb #{i}"
44
- end
27
+ ruby "-Ilib ./example.rb"
28
+ ruby "-Ilib ./example.rb 1000000 12" # 12 is the bignum cutoff for factorial
45
29
  end
46
30
  end
File without changes
data/example.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/local/bin/ruby -w
2
2
 
3
- begin require 'rubygems' rescue LoadError end
3
+ begin
4
+ require 'rubygems'
5
+ rescue LoadError
6
+ $: << 'lib'
7
+ end
4
8
  require 'inline'
5
9
 
6
10
  class MyTest
@@ -30,45 +34,53 @@ class MyTest
30
34
  end
31
35
  end
32
36
 
33
- t = MyTest.new()
34
-
35
- arg = ARGV.shift || 0
36
- arg = arg.to_i
37
-
38
37
  # breakeven for build run vs native doing 5 factorial:
39
38
  # on a PIII/750 running FreeBSD: about 5000
40
39
  # on a PPC/G4/800 running Mac OSX 10.2: always faster
41
- max = ARGV.shift || 1000000
42
- max = max.to_i
43
40
 
41
+ require 'benchmark'
44
42
  puts "RubyInline #{Inline::VERSION}" if $DEBUG
45
43
 
46
44
  MyTest.send(:alias_method, :factorial_alias, :factorial_c_raw)
47
45
 
48
- def validate(n)
49
- if n != 120 then puts "ACK! - #{n}"; end
50
- end
46
+ t = MyTest.new()
47
+ max = (ARGV.shift || 1_000_000).to_i
48
+ n = (ARGV.shift || 5).to_i
49
+ m = t.factorial(n)
51
50
 
52
- tstart = Time.now
53
- case arg
54
- when 0 then
55
- type = "Inline C "
56
- (1..max).each { |m| n = t.factorial_c(5); validate(n); }
57
- when 1 then
58
- type = "InlineRaw"
59
- (1..max).each { |m| n = t.factorial_c_raw(5); validate(n); }
60
- when 2 then
61
- type = "Alias "
62
- (1..max).each { |m| n = t.factorial_alias(5); validate(n); }
63
- when 3 then
64
- type = "Native "
65
- (1..max).each { |m| n = t.factorial(5); validate(n); }
66
- else
67
- $stderr.puts "ERROR: argument #{arg} not recognized"
68
- exit(1)
51
+ def validate(n, m)
52
+ if n != m then raise "#{n} != #{m}"; end
69
53
  end
70
- tend = Time.now
71
54
 
72
- total = tend - tstart
73
- avg = total / max
74
- printf "Type = #{type}, Iter = #{max}, T = %.8f sec, %.8f sec / iter\n", total, avg
55
+ puts "# of iterations = #{max}, n = #{n}"
56
+ Benchmark::bm(20) do |x|
57
+ x.report("null_time") do
58
+ for i in 0..max do
59
+ # do nothing
60
+ end
61
+ end
62
+
63
+ x.report("c") do
64
+ for i in 0..max do
65
+ validate(t.factorial_c(n), m)
66
+ end
67
+ end
68
+
69
+ x.report("c-raw") do
70
+ for i in 0..max do
71
+ validate(t.factorial_c_raw(n), m)
72
+ end
73
+ end
74
+
75
+ x.report("c-alias") do
76
+ for i in 0..max do
77
+ validate(t.factorial_alias(n), m)
78
+ end
79
+ end
80
+
81
+ x.report("pure ruby") do
82
+ for i in 0..max do
83
+ validate(t.factorial(n), m)
84
+ end
85
+ end
86
+ end
data/example2.rb CHANGED
@@ -1,6 +1,11 @@
1
1
  #!/usr/local/bin/ruby17 -w
2
2
 
3
- require "inline"
3
+ begin
4
+ require 'rubygems'
5
+ rescue LoadError
6
+ $: << 'lib'
7
+ end
8
+ require 'inline'
4
9
 
5
10
  class MyTest
6
11
 
@@ -19,9 +19,9 @@
19
19
  # }
20
20
  # end
21
21
  # end
22
- #
22
+ #
23
23
  # = DESCRIPTION
24
- #
24
+ #
25
25
  # Inline allows you to write foreign code within your ruby code. It
26
26
  # automatically determines if the code in question has changed and
27
27
  # builds it only when necessary. The extensions are then automatically
@@ -51,8 +51,8 @@ class CompilationError < RuntimeError; end
51
51
  # the current namespace.
52
52
 
53
53
  module Inline
54
- VERSION = '3.6.2'
55
-
54
+ VERSION = '3.6.3'
55
+
56
56
  WINDOZE = /win32/ =~ RUBY_PLATFORM
57
57
  DEV_NULL = (WINDOZE ? 'nul' : '/dev/null')
58
58
  RAKE = (WINDOZE ? 'rake.cmd' : 'rake')
@@ -84,8 +84,8 @@ module Inline
84
84
  directory = File.join(rootdir, ".ruby_inline")
85
85
  unless defined? @@directory and directory == @@directory and test ?d, @@directory then
86
86
  unless File.directory? directory then
87
- $stderr.puts "NOTE: creating #{directory} for RubyInline" if $DEBUG
88
- Dir.mkdir directory, 0700
87
+ $stderr.puts "NOTE: creating #{directory} for RubyInline" if $DEBUG
88
+ Dir.mkdir directory, 0700
89
89
  end
90
90
  Dir.assert_secure directory
91
91
  @@directory = directory
@@ -97,8 +97,8 @@ module Inline
97
97
  # Inline. It can be used as a template to write builders for other
98
98
  # languages. It understands type-conversions for the basic types and
99
99
  # can be extended as needed.
100
-
101
- class C
100
+
101
+ class C
102
102
 
103
103
  protected unless $TESTING
104
104
 
@@ -109,23 +109,23 @@ module Inline
109
109
  'char' => [ 'NUM2CHR', 'CHR2FIX' ],
110
110
  'char *' => [ 'STR2CSTR', 'rb_str_new2' ],
111
111
  'double' => [ 'NUM2DBL', 'rb_float_new' ],
112
- 'int' => [ 'FIX2INT', 'INT2FIX' ],
112
+ 'int' => [ 'F'+'IX2INT', 'INT2FIX' ],
113
113
  'long' => [ 'NUM2INT', 'INT2NUM' ],
114
114
  'unsigned int' => [ 'NUM2UINT', 'UINT2NUM' ],
115
115
  'unsigned long' => [ 'NUM2UINT', 'UINT2NUM' ],
116
116
  'unsigned' => [ 'NUM2UINT', 'UINT2NUM' ],
117
117
  'VALUE' => [ '', '' ],
118
118
  # Can't do these converters because they conflict with the above:
119
- # ID2SYM(x), SYM2ID(x), NUM2DBL(x), FIX2UINT(x)
119
+ # ID2SYM(x), SYM2ID(x), NUM2DBL(x), F\IX2UINT(x)
120
120
  }
121
121
 
122
122
  def ruby2c(type)
123
- raise ArgumentError, "Unknown type #{type}" unless @@type_map.has_key? type
123
+ raise ArgumentError, "Unknown type #{type.inspect}" unless @@type_map.has_key? type
124
124
  @@type_map[type].first
125
125
  end
126
126
 
127
127
  def c2ruby(type)
128
- raise ArgumentError, "Unknown type #{type}" unless @@type_map.has_key? type
128
+ raise ArgumentError, "Unknown type #{type.inspect}" unless @@type_map.has_key? type
129
129
  @@type_map[type].last
130
130
  end
131
131
 
@@ -137,7 +137,7 @@ module Inline
137
137
  src = src.gsub(%r%[ \t]*//[^\n]*%, '')
138
138
  src
139
139
  end
140
-
140
+
141
141
  def parse_signature(src, raw=false)
142
142
 
143
143
  sig = self.strip_comments(src)
@@ -153,29 +153,29 @@ module Inline
153
153
  end
154
154
 
155
155
  if /(#{@types})\s*(\w+)\s*\(([^)]*)\)/ =~ sig then
156
- return_type, function_name, arg_string = $1, $2, $3
157
- args = []
158
- arg_string.split(',').each do |arg|
159
-
160
- # helps normalize into 'char * varname' form
161
- arg = arg.gsub(/\s*\*\s*/, ' * ').strip
162
-
163
- if /(((#{@types})\s*\*?)+)\s+(\w+)\s*$/ =~ arg then
164
- args.push([$4, $1])
165
- elsif arg != "void" then
166
- $stderr.puts "WARNING: '#{arg}' not understood"
167
- end
168
- end
169
-
170
- arity = args.size
171
- arity = MAGIC_ARITY if raw
172
-
173
- return {
174
- 'return' => return_type,
175
- 'name' => function_name,
176
- 'args' => args,
177
- 'arity' => arity
178
- }
156
+ return_type, function_name, arg_string = $1, $2, $3
157
+ args = []
158
+ arg_string.split(',').each do |arg|
159
+
160
+ # helps normalize into 'char * varname' form
161
+ arg = arg.gsub(/\s*\*\s*/, ' * ').strip
162
+
163
+ if /(((#{@types})\s*\*?)+)\s+(\w+)\s*$/ =~ arg then
164
+ args.push([$4, $1])
165
+ elsif arg != "void" then
166
+ $stderr.puts "WAR\NING: '#{arg}' not understood"
167
+ end
168
+ end
169
+
170
+ arity = args.size
171
+ arity = MAGIC_ARITY if raw
172
+
173
+ return {
174
+ 'return' => return_type,
175
+ 'name' => function_name,
176
+ 'args' => args,
177
+ 'arity' => arity
178
+ }
179
179
  end
180
180
 
181
181
  raise SyntaxError, "Can't parse signature: #{sig}"
@@ -190,46 +190,47 @@ module Inline
190
190
 
191
191
  signature = parse_signature(src, !expand_types)
192
192
  function_name = signature['name']
193
+ method_name = options[:method_name] || function_name
193
194
  return_type = signature['return']
194
195
  arity = signature['arity']
195
196
 
196
197
  raise ArgumentError, "too many arguments" if arity > MAGIC_ARITY_THRESHOLD
197
198
 
198
199
  if expand_types then
199
- prefix = "static VALUE #{function_name}("
200
- if arity == MAGIC_ARITY then
201
- prefix += "int argc, VALUE *argv, VALUE self"
202
- else
203
- prefix += "VALUE self"
200
+ prefix = "static VALUE #{function_name}("
201
+ if arity == MAGIC_ARITY then
202
+ prefix += "int argc, VALUE *argv, VALUE self"
203
+ else
204
+ prefix += "VALUE self"
204
205
  prefix += signature['args'].map { |arg, type| ", VALUE _#{arg}"}.join
205
- end
206
- prefix += ") {\n"
206
+ end
207
+ prefix += ") {\n"
207
208
  prefix += signature['args'].map { |arg, type|
208
209
  " #{type} #{arg} = #{ruby2c(type)}(_#{arg});\n"
209
210
  }.join
210
211
 
211
- # replace the function signature (hopefully) with new sig (prefix)
212
- result.sub!(/[^;\/\"\>]+#{function_name}\s*\([^\{]+\{/, "\n" + prefix)
213
- result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
214
- unless return_type == "void" then
215
- raise SyntaxError, "Couldn't find return statement for #{function_name}" unless
216
- result =~ /return/
217
- result.gsub!(/return\s+([^\;\}]+)/) do
218
- "return #{c2ruby(return_type)}(#{$1})"
219
- end
220
- else
221
- result.sub!(/\s*\}\s*\Z/, "\nreturn Qnil;\n}")
222
- end
212
+ # replace the function signature (hopefully) with new sig (prefix)
213
+ result.sub!(/[^;\/\"\>]+#{function_name}\s*\([^\{]+\{/, "\n" + prefix)
214
+ result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
215
+ unless return_type == "void" then
216
+ raise SyntaxError, "Couldn't find return statement for #{function_name}" unless
217
+ result =~ /return/
218
+ result.gsub!(/return\s+([^\;\}]+)/) do
219
+ "return #{c2ruby(return_type)}(#{$1})"
220
+ end
221
+ else
222
+ result.sub!(/\s*\}\s*\Z/, "\nreturn Qnil;\n}")
223
+ end
223
224
  else
224
- prefix = "static #{return_type} #{function_name}("
225
- result.sub!(/[^;\/\"\>]+#{function_name}\s*\(/, prefix)
226
- result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
225
+ prefix = "static #{return_type} #{function_name}("
226
+ result.sub!(/[^;\/\"\>]+#{function_name}\s*\(/, prefix)
227
+ result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
227
228
  end
228
229
 
229
230
  delta = if result =~ /\A(static.*?\{)/m then
230
231
  $1.split(/\n/).size
231
232
  else
232
- warn "WARNING: Can't find signature in #{result.inspect}\n" unless $TESTING
233
+ warn "WAR\NING: Can't find signature in #{result.inspect}\n" unless $TESTING
233
234
  0
234
235
  end
235
236
 
@@ -237,7 +238,7 @@ module Inline
237
238
  result = "# line #{line.to_i + delta} \"#{file}\"\n" + result unless $DEBUG and not $TESTING
238
239
 
239
240
  @src << result
240
- @sig[function_name] = [arity,singleton]
241
+ @sig[function_name] = [arity,singleton,method_name]
241
242
 
242
243
  return result if $TESTING
243
244
  end # def generate
@@ -291,7 +292,7 @@ module Inline
291
292
  file = File.join("inline", File.basename(so_name))
292
293
  if require file then
293
294
  dir = Inline.directory
294
- warn "WARNING: #{dir} exists but is not being used" if test ?d, dir
295
+ warn "WAR\NING: #{dir} exists but is not being used" if test ?d, dir
295
296
  return true
296
297
  end
297
298
  rescue LoadError
@@ -313,21 +314,21 @@ module Inline
313
314
  so_name = self.so_name
314
315
  so_exists = File.file? so_name
315
316
  unless so_exists and File.mtime(rb_file) < File.mtime(so_name)
316
-
317
- src_name = "#{Inline.directory}/#{module_name}.c"
318
- old_src_name = "#{src_name}.old"
319
- should_compare = File.write_with_backup(src_name) do |io|
320
- io.puts
321
- io.puts "#include \"ruby.h\""
322
- io.puts
323
- io.puts @src.join("\n\n")
324
- io.puts
325
- io.puts
326
- io.puts "#ifdef __cplusplus"
327
- io.puts "extern \"C\" {"
328
- io.puts "#endif"
317
+
318
+ src_name = "#{Inline.directory}/#{module_name}.c"
319
+ old_src_name = "#{src_name}.old"
320
+ should_compare = File.write_with_backup(src_name) do |io|
321
+ io.puts
322
+ io.puts "#include \"ruby.h\""
323
+ io.puts
324
+ io.puts @src.join("\n\n")
325
+ io.puts
326
+ io.puts
327
+ io.puts "#ifdef __cplusplus"
328
+ io.puts "extern \"C\" {"
329
+ io.puts "#endif"
329
330
  io.puts " __declspec(dllexport)" if WINDOZE
330
- io.puts " void Init_#{module_name}() {"
331
+ io.puts " void Init_#{module_name}() {"
331
332
  io.puts " VALUE c = rb_cObject;"
332
333
 
333
334
  # TODO: use rb_class2path
@@ -335,71 +336,53 @@ module Inline
335
336
  " c = rb_const_get_at(c,rb_intern(\"#{n}\"));"
336
337
  }.join("\n")
337
338
 
338
- @sig.keys.sort.each do |name|
339
- arity, singleton = @sig[name]
339
+ @sig.keys.sort.each do |name|
340
+ arity, singleton, method_name = @sig[name]
340
341
  if singleton then
341
- io.print " rb_define_singleton_method(c, \"#{name}\", "
342
+ io.print " rb_define_singleton_method(c, \"#{method_name}\", "
342
343
  else
343
- io.print " rb_define_method(c, \"#{name}\", "
344
+ io.print " rb_define_method(c, \"#{method_name}\", "
344
345
  end
345
- io.puts "(VALUE(*)(ANYARGS))#{name}, #{arity});"
346
- end
347
-
346
+ io.puts "(VALUE(*)(ANYARGS))#{name}, #{arity});"
347
+ end
348
348
  io.puts @init_extra.join("\n") unless @init_extra.empty?
349
349
 
350
- io.puts
351
- io.puts " }"
352
- io.puts "#ifdef __cplusplus"
353
- io.puts "}"
354
- io.puts "#endif"
355
- io.puts
356
- end
357
-
358
- # recompile only if the files are different
359
- recompile = true
360
- if so_exists and should_compare and
350
+ io.puts
351
+ io.puts " }"
352
+ io.puts "#ifdef __cplusplus"
353
+ io.puts "}"
354
+ io.puts "#endif"
355
+ io.puts
356
+ end
357
+
358
+ # recompile only if the files are different
359
+ recompile = true
360
+ if so_exists and should_compare and
361
361
  File::compare(old_src_name, src_name, $DEBUG) then
362
- recompile = false
362
+ recompile = false
363
363
 
364
- # Updates the timestamps on all the generated/compiled files.
365
- # Prevents us from entering this conditional unless the source
366
- # file changes again.
364
+ # Updates the timestamps on all the generated/compiled files.
365
+ # Prevents us from entering this conditional unless the source
366
+ # file changes again.
367
367
  t = Time.now
368
- File.utime(t, t, src_name, old_src_name, so_name)
369
- end
370
-
371
- if recompile then
372
-
373
- # extracted from mkmf.rb
374
- srcdir = Config::CONFIG["srcdir"]
375
- archdir = Config::CONFIG["archdir"]
376
- if File.exist? archdir + "/ruby.h" then
377
- hdrdir = archdir
378
- elsif File.exist? srcdir + "/ruby.h" then
379
- hdrdir = srcdir
380
- else
381
- $stderr.puts "ERROR: Can't find header files for ruby. Exiting..."
382
- exit 1
383
- end
384
-
385
- flags = @flags.join(' ')
386
- libs = @libs.join(' ')
387
-
388
- cmd = "#{Config::CONFIG['LDSHARED']} #{flags} #{Config::CONFIG['CFLAGS']} -I #{hdrdir} -o \"#{so_name}\" \"#{File.expand_path(src_name)}\" #{libs}"
389
-
390
- # gawd windoze land sucks
391
- case RUBY_PLATFORM
392
- when /mswin32/ then
393
- cmd += " -link /LIBPATH:\"#{Config::CONFIG['libdir']}\" /DEFAULTLIB:\"#{Config::CONFIG['LIBRUBY']}\" /INCREMENTAL:no /EXPORT:Init_#{module_name}"
394
- when /mingw32/ then
395
- cmd += " -Wl,--enable-auto-import -L#{Config::CONFIG['libdir']} -lmsvcrt-ruby18"
396
- when /i386-cygwin/ then
397
- cmd += ' -L/usr/local/lib -lruby.dll'
398
- end
368
+ File.utime(t, t, src_name, old_src_name, so_name)
369
+ end
370
+
371
+ if recompile then
372
+
373
+ hdrdir = %w(srcdir archdir).map { |name|
374
+ dir = Config::CONFIG[name]
375
+ }.find { |dir|
376
+ dir and File.exist? File.join(dir, "/ruby.h")
377
+ } or abort "ERROR: Can't find header dir for ruby. Exiting..."
399
378
 
379
+ flags = @flags.join(' ')
380
+ libs = @libs.join(' ')
381
+
382
+ cmd = "#{Config::CONFIG['LDSHARED']} #{flags} #{Config::CONFIG['CCDLFLAGS']} #{Config::CONFIG['CFLAGS']} -I #{hdrdir} -I #{Config::CONFIG['includedir']} -o \"#{so_name}\" \"#{File.expand_path(src_name)}\" #{libs}" + crap_for_windoze
400
383
  cmd += " 2> #{DEV_NULL}" if $TESTING and not $DEBUG
401
-
402
- $stderr.puts "Building #{so_name} with '#{cmd}'" if $DEBUG
384
+
385
+ $stderr.puts "Building #{so_name} with '#{cmd}'" if $DEBUG
403
386
  result = `#{cmd}`
404
387
  $stderr.puts "Output:\n#{result}" if $DEBUG
405
388
  if $? != 0 then
@@ -420,19 +403,36 @@ module Inline
420
403
  end
421
404
  end
422
405
 
423
- $stderr.puts "Built successfully" if $DEBUG
424
- end
406
+ $stderr.puts "Built successfully" if $DEBUG
407
+ end
425
408
 
426
409
  else
427
- $stderr.puts "#{so_name} is up to date" if $DEBUG
410
+ $stderr.puts "#{so_name} is up to date" if $DEBUG
428
411
  end # unless (file is out of date)
429
412
  end # def build
430
-
413
+
414
+ ##
415
+ # Returns extra compilation flags for windoze platforms. Ugh.
416
+
417
+ def crap_for_windoze
418
+ # gawd windoze land sucks
419
+ case RUBY_PLATFORM
420
+ when /mswin32/ then
421
+ " -link /LIBPATH:\"#{Config::CONFIG['libdir']}\" /DEFAULTLIB:\"#{Config::CONFIG['LIBRUBY']}\" /INCREMENTAL:no /EXPORT:Init_#{module_name}"
422
+ when /mingw32/ then
423
+ " -Wl,--enable-auto-import -L#{Config::CONFIG['libdir']} -lmsvcrt-ruby18"
424
+ when /i386-cygwin/ then
425
+ ' -L/usr/local/lib -lruby.dll'
426
+ else
427
+ ''
428
+ end
429
+ end
430
+
431
431
  ##
432
432
  # Adds compiler options to the compiler command line. No
433
433
  # preprocessing is done, so you must have all your dashes and
434
434
  # everything.
435
-
435
+
436
436
  def add_compile_flags(*flags)
437
437
  @flags.push(*flags)
438
438
  end
@@ -440,7 +440,7 @@ module Inline
440
440
  ##
441
441
  # Adds linker flags to the link command line. No preprocessing is
442
442
  # done, so you must have all your dashes and everything.
443
-
443
+
444
444
  def add_link_flags(*flags)
445
445
  @libs.push(*flags)
446
446
  end
@@ -454,61 +454,93 @@ module Inline
454
454
 
455
455
  ##
456
456
  # Registers C type-casts +r2c+ and +c2r+ for +type+.
457
-
457
+
458
458
  def add_type_converter(type, r2c, c2r)
459
- $stderr.puts "WARNING: overridding #{type} on #{caller[0]}" if @@type_map.has_key? type
459
+ $stderr.puts "WAR\NING: overridding #{type} on #{caller[0]}" if @@type_map.has_key? type
460
460
  @@type_map[type] = [r2c, c2r]
461
461
  end
462
462
 
463
+ ##
464
+ # Maps a ruby constant to C (with the same name)
465
+
466
+ def map_ruby_const(*names)
467
+ names.each do |name|
468
+ self.prefix "static VALUE #{name};"
469
+ self.add_to_init " #{name} = rb_const_get(c, rb_intern(#{name.to_s.inspect}));"
470
+ end
471
+ end
472
+
473
+ ##
474
+ # Maps a C constant to ruby (with the same
475
+ # name). +names_and_types+ is a hash that maps the name of the
476
+ # constant to its C type.
477
+
478
+ def map_c_const(names_and_types)
479
+ names_and_types.each do |name, typ|
480
+ self.add_to_init " rb_define_const(c, #{name.to_s.inspect}, #{c2ruby(typ.to_s)}(#{name}));"
481
+ end
482
+ end
483
+
463
484
  ##
464
485
  # Adds an include to the top of the file. Don't forget to use
465
486
  # quotes or angle brackets.
466
-
487
+
467
488
  def include(header)
468
489
  @src << "#include #{header}"
469
490
  end
470
491
 
471
492
  ##
472
493
  # Adds any amount of text/code to the source
473
-
494
+
474
495
  def prefix(code)
475
496
  @src << code
476
497
  end
477
498
 
478
499
  ##
479
500
  # Adds a C function to the source, including performing automatic
480
- # type conversion to arguments and the return value. Unknown type
481
- # conversions can be extended by using +add_type_converter+.
482
-
483
- def c src
484
- self.generate(src,:expand_types=>true)
501
+ # type conversion to arguments and the return value. The Ruby
502
+ # method name can be overridden by providing method_name. Unknown
503
+ # type conversions can be extended by using +add_type_converter+.
504
+
505
+ def c src, options = {}
506
+ options = {
507
+ :expand_types => true,
508
+ }.merge options
509
+ self.generate src, options
485
510
  end
486
511
 
487
512
  ##
488
513
  # Same as +c+, but adds a class function.
489
-
490
- def c_singleton src
491
- self.generate(src,:expand_types=>true,:singleton=>true)
514
+
515
+ def c_singleton src, options = {}
516
+ options = {
517
+ :expand_types => true,
518
+ :singleton => true,
519
+ }.merge options
520
+ self.generate src, options
492
521
  end
493
-
522
+
494
523
  ##
495
524
  # Adds a raw C function to the source. This version does not
496
525
  # perform any type conversion and must conform to the ruby/C
497
- # coding conventions.
498
-
499
- def c_raw src
500
- self.generate(src)
526
+ # coding conventions. The Ruby method name can be overridden
527
+ # by providing method_name.
528
+
529
+ def c_raw src, options = {}
530
+ self.generate src, options
501
531
  end
502
532
 
503
533
  ##
504
534
  # Same as +c_raw+, but adds a class function.
505
-
506
- def c_raw_singleton src
507
- self.generate(src, :singleton=>true)
535
+
536
+ def c_raw_singleton src, options = {}
537
+ options = {
538
+ :singleton => true,
539
+ }.merge options
540
+ self.generate src, options
508
541
  end
509
542
 
510
543
  end # class Inline::C
511
-
512
544
  class Packager
513
545
  attr_accessor :name, :version, :summary, :libs_copied, :inline_dir
514
546
 
@@ -548,7 +580,7 @@ module Inline
548
580
  return
549
581
  end
550
582
 
551
- rakefile = eval RAKEFILE_TEMPLATE
583
+ rakefile = eval RAKEFILE_TEMPLATE
552
584
 
553
585
  STDERR.puts "==> Generating Rakefile" unless $TESTING
554
586
  File.open 'Rakefile', 'w' do |fp|
@@ -561,7 +593,7 @@ module Inline
561
593
 
562
594
  cmd = "#{RAKE} package"
563
595
  cmd += "> #{DEV_NULL} 2> #{DEV_NULL}" if $TESTING unless $DEBUG
564
-
596
+
565
597
  if system cmd then
566
598
  unless $TESTING then
567
599
  STDERR.puts
@@ -576,7 +608,7 @@ module Inline
576
608
  unless defined? @gem_libs then
577
609
  @gem_libs = Dir.glob File.join(@inline_dir, "*.#{@ext}")
578
610
  files = Dir.glob(File.join('lib', '*')).select { |f| test ?f, f }
579
-
611
+
580
612
  @gem_libs.push(*files)
581
613
  @gem_libs.sort!
582
614
  end
@@ -599,11 +631,11 @@ class Module
599
631
  # Extends the Module class to have an inline method. The default
600
632
  # language/builder used is C, but can be specified with the +lang+
601
633
  # parameter.
602
-
634
+
603
635
  def inline(lang = :C, options={})
604
636
  case options
605
637
  when TrueClass, FalseClass then
606
- warn "WARNING: 2nd argument to inline is now a hash, changing to {:testing=>#{options}}" unless options
638
+ warn "WAR\NING: 2nd argument to inline is now a hash, changing to {:testing=>#{options}}" unless options
607
639
  options = { :testing => options }
608
640
  when Hash
609
641
  options[:testing] ||= false
@@ -637,9 +669,9 @@ class File
637
669
  ##
638
670
  # Equivalent to +File::open+ with an associated block, but moves
639
671
  # any existing file with the same name to the side first.
640
-
672
+
641
673
  def self.write_with_backup(path) # returns true if file already existed
642
-
674
+
643
675
  # move previous version to the side if it exists
644
676
  renamed = false
645
677
  if test ?f, path then
@@ -662,15 +694,15 @@ class Dir
662
694
  # writable permissions. If not, it prints an error and exits. It
663
695
  # only works on +POSIX+ systems. Patches for other systems are
664
696
  # welcome.
665
-
697
+
666
698
  def self.assert_secure(path)
667
699
  mode = File.stat(path).mode
668
700
  unless ((mode % 01000) & 0022) == 0 then
669
701
  if $TESTING then
670
- raise SecurityError, "Directory #{path} is insecure"
702
+ raise SecurityError, "Directory #{path} is insecure"
671
703
  else
672
- $stderr.puts "#{path} is insecure (#{'%o' % mode}). It may not be group or world writable. Exiting."
673
- exit 1
704
+ $stderr.puts "#{path} is insecure (#{'%o' % mode}). It may not be group or world writable. Exiting."
705
+ exit 1
674
706
  end
675
707
  end
676
708
  end
@@ -30,7 +30,7 @@ class InlineTestCase < Test::Unit::TestCase
30
30
 
31
31
  def teardown
32
32
  unless $DEBUG then
33
- FileUtils.rm_rf @rootdir
33
+ FileUtils.rm_rf @rootdir
34
34
  ENV.delete 'INLINEDIR'
35
35
  end
36
36
  end
@@ -178,7 +178,7 @@ class TestC < InlineTestCase
178
178
 
179
179
  @builder.add_type_converter t, a, b unless t.nil?
180
180
  result = @builder.parse_signature(src)
181
-
181
+
182
182
  assert_equal(expected, result)
183
183
  end
184
184
 
@@ -198,16 +198,16 @@ class TestC < InlineTestCase
198
198
  'return' => 'int',
199
199
  'arity' => 2,
200
200
  'args' => [
201
- ['x', 'int'],
202
- ['y', 'int']
201
+ ['x', 'int'],
202
+ ['y', 'int']
203
203
  ]
204
204
  }
205
-
205
+
206
206
  util_parse_signature(src, expected)
207
207
  end
208
-
208
+
209
209
  def test_parse_signature_custom
210
-
210
+
211
211
  src = "// stupid cpp comment
212
212
  #include \"header.h\"
213
213
  /* stupid c comment */
@@ -217,19 +217,19 @@ class TestC < InlineTestCase
217
217
  return result;
218
218
  }
219
219
  "
220
-
220
+
221
221
  expected = {
222
222
  'name' => 'add',
223
223
  'return' => 'int',
224
224
  'arity' => 2,
225
225
  'args' => [
226
- [ 'x', 'fooby' ],
227
- ['y', 'int']
226
+ [ 'x', 'fooby' ],
227
+ ['y', 'int']
228
228
  ]
229
229
  }
230
-
230
+
231
231
  util_parse_signature(src, expected,
232
- "fooby", "r2c_fooby", "c2r_fooby")
232
+ "fooby", "r2c_fooby", "c2r_fooby")
233
233
  end
234
234
 
235
235
  def test_parse_signature_register
@@ -249,14 +249,14 @@ class TestC < InlineTestCase
249
249
  'return' => 'int',
250
250
  'arity' => 2,
251
251
  'args' => [
252
- [ 'x', 'register int' ],
253
- ['y', 'int']
252
+ [ 'x', 'register int' ],
253
+ ['y', 'int']
254
254
  ]
255
255
  }
256
256
 
257
-
257
+
258
258
  util_parse_signature(src, expected,
259
- "register int", 'FIX2INT', 'INT2FIX')
259
+ "register int", 'FIX2INT', 'INT2FIX')
260
260
  end
261
261
 
262
262
  def util_generate(src, expected, expand_types=true)
@@ -532,7 +532,7 @@ puts(s); return rb_str_new2(s)}"
532
532
 
533
533
  def test_build_bad
534
534
  code = util_simple_code(:DumbTest2, "void should_puke() { 1+1 2+2 }")
535
- assert_raises(CompilationError) do
535
+ assert_raises(CompilationError) do
536
536
  util_test_build(code) do
537
537
  flunk
538
538
  end
@@ -650,7 +650,7 @@ class TestModule < InlineTestCase
650
650
 
651
651
  def test_argument_check_fewer
652
652
  fb = Foo::Bar.new
653
-
653
+
654
654
  assert_raise(ArgumentError) do
655
655
  assert_equal 13, fb.arity6(1, 2, 3)
656
656
  end
@@ -668,12 +668,12 @@ class TestModule < InlineTestCase
668
668
  builder.c "int add(int a, int b) { return a + b; }"
669
669
  end
670
670
  assert(test(?d, Inline.directory),
671
- "inline dir should have been created")
671
+ "inline dir should have been created")
672
672
  matches = Dir[File.join(Inline.directory, "Inline_TestModule_*.c")]
673
673
  assert_equal(1, matches.length, "Source should have been created")
674
674
  library_file = matches.first.gsub(/\.c$/) { "." + Config::CONFIG["DLEXT"] }
675
675
  assert(test(?f, library_file),
676
- "Library file should have been created")
676
+ "Library file should have been created")
677
677
  end
678
678
 
679
679
  end
@@ -721,7 +721,7 @@ class TestInlinePackager < InlineTestCase
721
721
  @packager.package
722
722
  end
723
723
  end
724
-
724
+
725
725
  def test_copy_libs
726
726
  assert_equal false, @packager.libs_copied
727
727
 
@@ -744,7 +744,7 @@ class TestInlinePackager < InlineTestCase
744
744
  def test_generate_rakefile_has_rakefile
745
745
  FileUtils.rm 'Rakefile' if test ?f, 'Rakefile' and $DEBUG
746
746
  FileUtils.touch 'Rakefile'
747
-
747
+
748
748
  @packager.generate_rakefile
749
749
 
750
750
  assert_equal "", File.read('Rakefile')
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.0.9
3
3
  specification_version: 1
4
4
  name: RubyInline
5
5
  version: !ruby/object:Gem::Version
6
- version: 3.6.2
7
- date: 2006-10-12 00:00:00 -07:00
6
+ version: 3.6.3
7
+ date: 2007-04-27 00:00:00 -07:00
8
8
  summary: Multi-language extension coding within ruby.
9
9
  require_paths:
10
- - .
10
+ - lib
11
11
  email: ryand-ruby@zenspider.com
12
- homepage: http://www.zenspider.com/ZSS/Products/RubyInline/
12
+ homepage: " http://rubyforge.org/projects/rubyinline/\n"
13
13
  rubyforge_project: rubyinline
14
14
  description: Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.
15
15
  autorequire:
@@ -33,23 +33,23 @@ files:
33
33
  - Manifest.txt
34
34
  - README.txt
35
35
  - Rakefile
36
+ - bin/inline_package
36
37
  - demo/fastmath.rb
37
38
  - demo/hello.rb
38
39
  - example.rb
39
40
  - example2.rb
40
- - inline.rb
41
- - inline_package
42
- - test_inline.rb
41
+ - lib/inline.rb
42
+ - test/test_inline.rb
43
43
  - tutorial/example1.rb
44
44
  - tutorial/example2.rb
45
- test_files: []
46
-
45
+ test_files:
46
+ - test/test_inline.rb
47
47
  rdoc_options: []
48
48
 
49
49
  extra_rdoc_files: []
50
50
 
51
- executables: []
52
-
51
+ executables:
52
+ - inline_package
53
53
  extensions: []
54
54
 
55
55
  requirements:
@@ -62,5 +62,5 @@ dependencies:
62
62
  requirements:
63
63
  - - ">="
64
64
  - !ruby/object:Gem::Version
65
- version: 1.1.1
65
+ version: 1.2.0
66
66
  version: