Module: Rubber
- Defined in:
- lib/rubber/types.rb,
lib/rubber/autord.rb,
lib/rubber/tokens.rb,
lib/rubber/codegen.rb,
lib/rubber/scanner.rb,
lib/rubber/version.rb,
lib/rubber/mkextconf.rb,
lib/rubber/codegen/enum.rb,
lib/rubber/codegen/array.rb,
lib/rubber/codegen/class.rb,
lib/rubber/codegen/flags.rb,
lib/rubber/codegen/float.rb,
lib/rubber/codegen/genum.rb,
lib/rubber/codegen/param.rb,
lib/rubber/codegen/gboxed.rb,
lib/rubber/codegen/gflags.rb,
lib/rubber/codegen/module.rb,
lib/rubber/codegen/string.rb,
lib/rubber/codegen/struct.rb,
lib/rubber/codegen/gobject.rb,
lib/rubber/codegen/integer.rb,
lib/rubber/codegen/function.rb,
lib/rubber/codegen/gcrefpool.rb,
lib/rubber/codegen/ginterface.rb
Defined Under Namespace
Modules: RegisterChildren
Classes: CRScanner, C_Array, C_Class, C_Enum, C_Flags, C_Float, C_Function, C_GBoxed, C_GCRefPool, C_GEnum, C_GFlags, C_GInterface, C_GObject, C_Integer, C_Module, C_Param, C_RootModule, C_String, C_Struct, Options, ScanState, TokenStringScanner, Tokenizer
Constant Summary
collapse
- CMAP =
Map most GLib types to normal C style ones
{
'ruby'=>'VALUE',
'gboolean'=>'bool',
'gint'=>'int',
'glong'=>'long',
'guint'=>'uint',
'guint64'=>'uint64',
'gchar'=>'char',
'gfloat'=>'double', 'float'=>'double', 'gdouble'=>'double'
}
- RUBY_CLASS_MAP =
auto_class_map()
- RUBY_NATIVE_TYPES =
%w|T_NIL T_OBJECT T_CLASS T_MODULE T_FLOAT T_STRING T_REGEXP T_ARRAY T_FIXNUM T_HASH T_STRUCT T_BIGNUM T_FILE T_TRUE T_FALSE T_DATA T_SYMBOL|
- RUBY_NATIVE_NAMES =
%w|Nil Object Class Module Float String Regexp Array Fixnum Hash Struct Bignum File True False Data Symbol|
- VERSION =
[0,0,22]
Class Method Summary
collapse
Class Method Details
.auto_class_map ⇒ Object
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/rubber/types.rb', line 20
def auto_class_map()
hsh = {}
%w[rb_cObject
rb_cArray
rb_cBignum
rb_cClass
rb_cDir
rb_cData
rb_cFalseClass
rb_cFile
rb_cFixnum
rb_cFloat
rb_cHash
rb_cInteger
rb_cIO
rb_cModule
rb_cNilClass
rb_cNumeric
rb_cProc
rb_cRange
rb_cRegexp
rb_cString
rb_cSymbol
rb_cThread
rb_cTime
rb_cTrueClass
rb_cStruct
rb_eException
rb_eStandardError
rb_eSystemExit
rb_eInterrupt
rb_eSignal
rb_eFatal
rb_eArgError
rb_eEOFError
rb_eIndexError
rb_eRangeError
rb_eIOError
rb_eRuntimeError
rb_eSecurityError
rb_eSystemCallError
rb_eTypeError
rb_eZeroDivError
rb_eNotImpError
rb_eNoMemError
rb_eNoMethodError
rb_eFloatDomainError
rb_eScriptError
rb_eNameError
rb_eSyntaxError
rb_eLoadError].each { |n|
hsh[$1]= n.strip if n =~ /rb_[ce]([A-Za-z]+)/
}
hsh
end
|
.count_arr_access(str, name) ⇒ Object
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/rubber/types.rb', line 95
def self.count_arr_access(str,name)
if name.include?(?[)
sc = StringIO.new(name)
brac, lev = 0, 0
until sc.eof?
c = sc.getc
if lev == 0 and c == ?[
brac += 1
end
case c
when ?[
lev += 1
when ?]
lev -= 1
end
end
brac
else
0
end
end
|
.equivalent_type(ctype, name = nil) ⇒ Object
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/rubber/types.rb', line 117
def self.equivalent_type(ctype,name=nil)
ctype.gsub!(/ /,'')
ctype.strip!
ctype.gsub!(/(const|static)/,'')
if name
brackets = count_arr_access(ctype,name)
until brackets == 0
ctype = ctype[0..-2] if ctype[-1] == ?*
brackets -= 1
end
end
return 'VALUE' if RUBY_NATIVE_TYPES.include?(ctype)
ctype= $equivalents[ctype] if $equivalents.has_key?(ctype)
return 'VALUE' if RUBY_NATIVE_TYPES.include?(ctype)
ctype= CMAP[ctype] if CMAP.has_key?(ctype)
ctype
end
|
.explicit_cast(name, ctype, rule) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
# File 'lib/rubber/types.rb', line 135
def self.explicit_cast(name, ctype, rule)
ctype = equivalent_type(ctype, name)
rule = equivalent_type(rule)
return name if ctype == rule
if $custom_maps.has_key?(ctype)
if $custom_maps[ctype].has_key?(rule)
return $custom_maps[ctype][rule].gsub(/%%/,"#{name}")
end
end
case ctype
when 'VALUE'
case rule
when 'char*', 'string'
"( NIL_P(#{name}) ? NULL : StringValuePtr(#{name}) )"
when 'bool'
"RTEST(#{name})"
when 'int'
"NUM2INT(#{name})"
when 'uint'
"NUM2UINT(#{name})"
when 'uint64'
"rb_num2ull(#{name})"
when 'long'
"NUM2LONG(#{name})"
when 'double'
"NUM2DBL(#{name})"
when 'gobject', 'GObject*'
"RVAL2GOBJ(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'bool'
case rule
when 'char*', 'string'
"#{name} ? #{"true".inspect} : #{"false".inspect}"
when 'VALUE', 'ruby'
" ((#{name}) ? Qtrue : Qfalse)"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'uint'
case rule
when 'VALUE', 'ruby'
" UINT2NUM(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'uint64'
case rule
when 'VALUE', 'ruby'
" rb_ull2inum(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'char*', 'string'
case rule
when 'VALUE', 'ruby'
" rb_str_new2(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'GObject*', 'gobject'
case rule
when 'VALUE', 'ruby'
" GOBJ2RVAL(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'int'
case rule
when 'VALUE', 'ruby'
" INT2NUM(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'long'
case rule
when 'VALUE', 'ruby'
" LONG2NUM(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
when 'double'
case rule
when 'VALUE', 'ruby'
" rb_float_new(#{name})"
else
raise "Unable to convert #{ctype} to #{rule}"
end
else
raise "Unable to convert #{ctype} to #{rule}"
end
end
|
.find_class(classname) ⇒ Object
79
80
81
82
83
84
85
|
# File 'lib/rubber/types.rb', line 79
def self.find_class(classname)
return nil if classname.nil?
return RUBY_CLASS_MAP[classname] if RUBY_CLASS_MAP.has_key?(classname)
return 'c'+classname
end
|
.generate_c_source(scanner, io) ⇒ Object
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/rubber/codegen.rb', line 3
def generate_c_source(scanner, io)
mod = scanner.stack.first if scanner.options.gnu
io.puts "#define _GNU_SOURCE 1"
end
io.puts <<-EOX
/* Includes */
#include <ruby.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined GCC
#define OPTIONAL_ATTR __attribute__((unused))
#else
#define OPTIONAL_ATTR
#endif
EOX
if scanner.incs
scanner.incs.each { |i| io.puts "#include #{i.inspect}"}
end
io.puts "\n/* Setup types */"
io.puts "/* Try not to clash with other definitions of bool... */"
io.puts "typedef int rubber_bool;"
io.puts "#define bool rubber_bool"
io.puts "\n/* Prototypes */"
if scanner.options.glib?
io.puts <<-EOGLIB
#include "rbglib.h"
EOGLIB
if scanner.options.gtk?
io.write <<-EOI
#include "rbgtk.h"
#if defined(G_PLATFORM_WIN32) && !defined(RUBY_GTK2_STATIC_COMPILATION)
# ifdef RUBY_GTK2_COMPILATION
# define RUBY_GTK2_VAR __declspec(dllexport)
# else
# define RUBY_GTK2_VAR extern __declspec(dllimport)
# endif
#else
# define RUBY_GTK2_VAR extern
#endif
RUBY_GTK2_VAR VALUE mGtk;
RUBY_GTK2_VAR VALUE mGdk;
#define RBGTK_INITIALIZE(obj,gtkobj)\
(rbgtk_initialize_gtkobject(obj, GTK_OBJECT(gtkobj)))
EOI
end
end
mod.classes.each { |c|
c.declare(io)
}
if scanner.raw
io.puts("\n/* Inline C code */")
io.write(scanner.raw)
end
io.puts "\n/* Code */"
mod.classes.each { |c|
c.code(io)
}
io.puts "/* Init */"
io.puts "void"
io.puts "Init_#{scanner.ext}(void)"
io.puts "{"
io.puts scanner.pre_init_code if scanner.pre_init_code
mod.classes.each { |c|
c.register(io)
}
io.puts scanner.post_init_code if scanner.post_init_code
io.puts "}"
end
|
.generate_extconf(scanner, io) ⇒ Object
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/rubber/mkextconf.rb', line 3
def generate_extconf(scanner, io)
io.write <<-EOMK
require 'mkmf'
use_gems = false
begin
require 'mkmf-gnome2'
rescue LoadError
use_gems = true
end
if use_gems or Object.const_defined?('Gem')
require 'rubygems'
gem 'glib2'
require 'mkmf-gnome2'
%w[rbglib.h rbgtk.h rbpango.h rbatk.h].each do |header|
Gem.find_files(header).each do |f|
$CFLAGS += " '-I\#{File.dirname(f)}'"
end
end
end
EOMK
io.write <<-EOMK
# Look for headers in {gem_root}/ext/{package}
if use_gems
%w[
EOMK
io << " glib2" if scanner.options.glib
io << " gdk_pixbuf2 atk gtk2" if scanner.options.gtk
io.write <<-EOX
].each do |package|
require package
if Gem.loaded_specs[package]
$CFLAGS += " -I" + Gem.loaded_specs[package].full_gem_path + "/ext/" + package
else
if fn = $".find { |n| n.sub(/[.](so|rb)$/,'') == package }
dr = $:.find { |d| File.exist?(File.join(d, fn)) }
pt = File.join(dr,fn) if dr && fn
else
pt = "??"
end
STDERR.puts "require '" + package + "' loaded '"+pt+"' instead of the gem - trying to continue, but build may fail"
end
end
end
EOX
io.write <<-EOY
if RbConfig::CONFIG.has_key?('rubyhdrdir')
$CFLAGS += " -I" + RbConfig::CONFIG['rubyhdrdir']+'/ruby'
end
$CFLAGS += " -I."
have_func("rb_errinfo")
EOY
if scanner.inc_dirs
io.puts "$CFLAGS += "+scanner.inc_dirs.reject { |i| i =~ /:/ }.collect { |i| " '-I#{i}'" }.join().inspect
scanner.inc_dirs.select { |i| i =~ /gem:/ }.each do |gem_info|
name, = gem_info.split(/:/)[1].split(%r'/', 2)
= "/#{}" unless .nil? or .empty?
io.puts %Q<gem '#{name}'; $CFLAGS += " '-I" + Gem.loaded_specs['#{name}'].full_gem_path + "#{}'">
end
end
if scanner.lib_dirs
io.puts "$LDFLAGS += "+scanner.lib_dirs.collect { |i| " '-L#{i}'"}.join().inspect
end
if scanner.defs
io.puts "$CFLAGS += "+scanner.defs.collect { |i| " '-D#{i}'"}.join().inspect
end
scanner.pkgs.each { |pkg| io.puts "PKGConfig.have_package(#{pkg.inspect}) or exit(-1)" } if scanner.pkgs
if scanner.incs
scanner.incs.each { |i|
io.puts %Q<
unless have_header(#{i.inspect})
paths = Gem.find_files(#{i.inspect})
paths.each do |path|
$CFLAGS += " '-I\#{File.dirname(path)}'"
end
have_header(#{i.inspect}) or exit -1
end
>
}
end
if scanner.libs
scanner.libs.each { |i| io.puts "have_library(#{i.inspect}) or exit(-1)\n$LIBS += \" -l#{i}\""}
end
io.write <<-EOB
STDOUT.print("checking for new allocation framework... ") # for ruby-1.7
if Object.respond_to? :allocate
STDOUT.print "yes\n"
$defs << "-DHAVE_OBJECT_ALLOCATE"
else
STDOUT.print "no\n"
end
top = File.expand_path(File.dirname(__FILE__) + '/..') # XXX
$CFLAGS += " " + ['glib/src'].map{|d|
"-I" + File.join(top, d)
}.join(" ")
have_func("rb_define_alloc_func") # for ruby-1.8
#set_output_lib('libruby-#{scanner.ext}.a')
if /cygwin|mingw/ =~ RUBY_PLATFORM
top = "../.."
[
["glib/src", "ruby-glib2"],
].each{|d,l|
$LDFLAGS << sprintf(" -L%s/%s", top, d)
$libs << sprintf(" -l%s", l)
}
end
begin
srcdir = File.expand_path(File.dirname($0))
begin
obj_ext = "."+$OBJEXT
$libs = $libs.split(/\s/).uniq.join(' ')
$source_files = Dir.glob(sprintf("%s/*.c", srcdir)).map{|fname|
fname[0, srcdir.length+1] = ''
fname
}
$objs = $source_files.collect do |item|
item.gsub(/\.c$/, obj_ext)
end
#
# create Makefile
#
$defs << "-DRUBY_#{scanner.ext.upcase}_COMPILATION"
# $CFLAGS << $defs.join(' ')
create_makefile(#{scanner.ext.inspect}, srcdir)
raise Interrupt if not FileTest.exist? "Makefile"
File.open("Makefile", "a") do |mfile|
$source_files.each do |e|
mfile.print sprintf("%s: %s\n", e.gsub(/\.c$/, obj_ext), e)
end
end
ensure
#Dir.chdir ".."
end
#create_top_makefile()
rescue Interrupt
print " [error] " + $!.to_s + "\n"
end
EOB
end
|
.generate_rd(scanner, io) ⇒ Object
2
3
4
5
6
7
8
9
|
# File 'lib/rubber/autord.rb', line 2
def self.generate_rd(scanner, io)
if scanner.doc
io.write(scanner.doc + "\n\n")
end
scanner.stack.first.classes.each { |c|
c.doc_rd(io)
}
end
|
.native_type?(name) ⇒ Boolean
90
91
92
93
|
# File 'lib/rubber/types.rb', line 90
def self.native_type?(name)
return true if name.nil? or RUBY_NATIVE_TYPES.include?(equivalent_type(name))
false
end
|