rbplusplus 0.1.1 → 0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +31 -15
- data/TODO +20 -0
- data/lib/rbplusplus/builders/base.rb +148 -8
- data/lib/rbplusplus/builders/class.rb +106 -31
- data/lib/rbplusplus/builders/enumeration.rb +40 -0
- data/lib/rbplusplus/builders/extension.rb +31 -6
- data/lib/rbplusplus/builders/module.rb +12 -6
- data/lib/rbplusplus/builders/types_manager.rb +93 -0
- data/lib/rbplusplus/extension.rb +69 -41
- data/lib/rbplusplus/module.rb +3 -1
- data/lib/rbplusplus/transformers/class.rb +67 -0
- data/lib/rbplusplus/transformers/constructor.rb +4 -0
- data/lib/rbplusplus/transformers/function.rb +27 -0
- data/lib/rbplusplus/transformers/method.rb +4 -0
- data/lib/rbplusplus/transformers/module.rb +71 -0
- data/lib/rbplusplus/transformers/node.rb +77 -0
- data/lib/rbplusplus/transformers/node_cache.rb +19 -0
- data/lib/rbplusplus/transformers/node_reference.rb +30 -0
- data/lib/rbplusplus/transformers/rbgccxml.rb +6 -0
- data/lib/rbplusplus/writers/extension.rb +33 -25
- data/lib/rbplusplus/writers/multiple_files_writer.rb +42 -2
- data/lib/rbplusplus/writers/single_file_writer.rb +5 -0
- data/lib/rbplusplus.rb +24 -0
- data/test/class_methods_test.rb +55 -0
- data/test/classes_test.rb +0 -25
- data/test/compiling_test.rb +30 -0
- data/test/constructors_test.rb +40 -0
- data/test/enumerations_test.rb +63 -0
- data/test/file_writers_test.rb +56 -4
- data/test/generated/extconf.rb +25 -5
- data/test/headers/class_methods.h +41 -0
- data/test/headers/complex_static_methods.h +25 -0
- data/test/headers/constructors.h +47 -0
- data/test/headers/enums.h +77 -0
- data/test/headers/external_mapping.h +16 -0
- data/test/headers/external_mapping_rice.h +20 -0
- data/test/headers/include/helper.h +1 -0
- data/test/headers/nested_struct.h +20 -0
- data/test/headers/overload.h +28 -0
- data/test/headers/subclass.h +42 -0
- data/test/headers/to_from_ruby.h +78 -0
- data/test/headers/to_from_ruby_source.cpp +22 -0
- data/test/headers/ugly_helper.h +18 -0
- data/test/headers/ugly_interface.h +115 -0
- data/test/headers/ugly_interface_ns.h +8 -0
- data/test/nested_test.rb +26 -0
- data/test/object_persistence_test.rb +44 -0
- data/test/overloading_test.rb +36 -0
- data/test/struct_test.rb +22 -0
- data/test/subclass_test.rb +31 -0
- data/test/test_helper.rb +5 -0
- data/test/to_from_ruby_test.rb +24 -0
- data/test/wrap_as_test.rb +114 -0
- metadata +43 -6
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ require 'rake/rdoctask'
|
|
3
3
|
require 'rake/contrib/sshpublisher'
|
4
4
|
|
5
5
|
PROJECT_NAME = "rb++"
|
6
|
-
RBPLUSPLUS_VERSION = "0.
|
6
|
+
RBPLUSPLUS_VERSION = "0.8"
|
7
7
|
|
8
8
|
task :default => :test
|
9
9
|
|
@@ -11,12 +11,15 @@ task :default => :test
|
|
11
11
|
# The tests wrap and load C++ wrapper code constantly.
|
12
12
|
# When running all the tests at once, we very quickly run
|
13
13
|
# into problems where Rice crashes because
|
14
|
-
# a given C++ class is already wrapped
|
14
|
+
# a given C++ class is already wrapped, or glibc doesn't like our
|
15
|
+
# unorthodox handling of it's pieces. So we need to run the
|
15
16
|
# tests individually
|
16
17
|
desc "Run the tests"
|
17
18
|
task :test do
|
18
|
-
FileList["test/*_test.rb"]
|
19
|
-
|
19
|
+
files = FileList["test/*_test.rb"]
|
20
|
+
puts files.inspect
|
21
|
+
files.each do |file|
|
22
|
+
sh "ruby #{file}"
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
@@ -31,16 +34,29 @@ end
|
|
31
34
|
RUBYFORGE_USERNAME = "jameskilton"
|
32
35
|
PROJECT_WEB_PATH = "/var/www/gforge-projects/rbplusplus"
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
namespace :web do
|
38
|
+
desc "Build website"
|
39
|
+
task :build => :rdoc do |t|
|
40
|
+
cd "website" do
|
41
|
+
sh "webgen"
|
42
|
+
end
|
43
|
+
|
44
|
+
unless File.directory?("publish")
|
45
|
+
mkdir "publish"
|
46
|
+
end
|
47
|
+
sh "cp -r website/output/* publish/"
|
48
|
+
sh "cp -r html/* publish/rbplusplus/"
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Update the website"
|
52
|
+
task :upload => "web:build" do |t|
|
53
|
+
Rake::SshDirPublisher.new("#{RUBYFORGE_USERNAME}@rubyforge.org", PROJECT_WEB_PATH, "publish").upload
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Clean up generated website files"
|
57
|
+
task :clean do
|
58
|
+
rm_rf "publish"
|
39
59
|
end
|
40
|
-
sh "cp -r website publish/"
|
41
|
-
sh "cp -r html/* publish/rbplusplus/"
|
42
|
-
Rake::SshDirPublisher.new("#{RUBYFORGE_USERNAME}@rubyforge.org", PROJECT_WEB_PATH, "publish").upload
|
43
|
-
rm_rf "publish"
|
44
60
|
end
|
45
61
|
|
46
62
|
spec = Gem::Specification.new do |s|
|
@@ -57,8 +73,8 @@ Rb++ combines the powerful query interface of rbgccxml and the Rice library to
|
|
57
73
|
make Ruby wrapping extensions easier to write than ever.
|
58
74
|
END
|
59
75
|
|
60
|
-
s.add_dependency "rbgccxml", "0.
|
61
|
-
s.add_dependency "rice", "1.0.
|
76
|
+
s.add_dependency "rbgccxml", "0.8"
|
77
|
+
s.add_dependency "rice", ">= 1.0.2"
|
62
78
|
|
63
79
|
patterns = [
|
64
80
|
'TODO',
|
data/TODO
CHANGED
@@ -3,6 +3,21 @@ TODO
|
|
3
3
|
* Allowing use of "have_library"
|
4
4
|
* Other mkmf functions?
|
5
5
|
|
6
|
+
* rbgccxml: Continue working with QueryResult#find, making it as powerful
|
7
|
+
and robust as possible.
|
8
|
+
|
9
|
+
* Rest of the GCCXML types (as needed):
|
10
|
+
- ArrayType
|
11
|
+
- Converter
|
12
|
+
- Destructor
|
13
|
+
- Field
|
14
|
+
- FunctionType
|
15
|
+
- OperatorFunction
|
16
|
+
- OperatorMethod
|
17
|
+
- OffsetType
|
18
|
+
- Union
|
19
|
+
- Variable
|
20
|
+
|
6
21
|
STARTED
|
7
22
|
* Adding constructor
|
8
23
|
- Test constructor arguments
|
@@ -18,6 +33,11 @@ DONE
|
|
18
33
|
* Adding classes to classes (ad infinitum)
|
19
34
|
* Look into file naming when dealing with Modules
|
20
35
|
* Nested Modules
|
36
|
+
* Recognizing and building to_ruby / from_ruby methods for const type references
|
37
|
+
* Moving the to_ruby / from_ruby definitions to a place that all will know about them
|
38
|
+
* Enumerations
|
39
|
+
* Proper TypesManager dealings with single_file writer mode
|
40
|
+
* Working with the defined C++ heirarchy chain
|
21
41
|
|
22
42
|
No longer waiting on rice - just building a wrapper myself now.
|
23
43
|
* Adding global methods (Kernel-level methods)
|
@@ -54,6 +54,91 @@ module RbPlusPlus
|
|
54
54
|
@includes = []
|
55
55
|
@declarations = []
|
56
56
|
@body = []
|
57
|
+
@registered_nodes = []
|
58
|
+
end
|
59
|
+
|
60
|
+
# adds a register function to the Init or register of this node
|
61
|
+
def register_node(node, register_func)
|
62
|
+
@registered_nodes << [node, register_func]
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def nested_level(node, level=0)
|
68
|
+
return level if node.is_a?(RbGCCXML::Namespace) || node.is_a?(RbGCCXML::Enumeration)
|
69
|
+
return level if node.super_classes.length == 0
|
70
|
+
node.super_classes.each do |sup|
|
71
|
+
level = nested_level(sup, level+1)
|
72
|
+
end
|
73
|
+
return level
|
74
|
+
end
|
75
|
+
|
76
|
+
public
|
77
|
+
|
78
|
+
# Sorts the registered nodes by hierachy, registering the base classes
|
79
|
+
# first.
|
80
|
+
#
|
81
|
+
# this is necessary for Rice to know about inheritance
|
82
|
+
def registered_nodes
|
83
|
+
#sort by hierachy
|
84
|
+
nodes = @registered_nodes.sort_by do |build, func|
|
85
|
+
if build.node.nil?
|
86
|
+
0
|
87
|
+
else
|
88
|
+
nested_level(build.node)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#collect the sorted members
|
93
|
+
nodes.collect do |node, func|
|
94
|
+
func
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# The name of the header file to include
|
99
|
+
# This is the file default, so long as it matches one of the export files
|
100
|
+
# If not this returns all exported files.
|
101
|
+
#
|
102
|
+
# This was added to workaround badly declared namespaces
|
103
|
+
def header_files(node)
|
104
|
+
file = node.file_name(false)
|
105
|
+
return [file] if self.class.sources.include?(file)
|
106
|
+
self.class.sources
|
107
|
+
end
|
108
|
+
|
109
|
+
# Adds the necessary includes in order to compile the specified node
|
110
|
+
def add_includes_for(node)
|
111
|
+
header_files(node).each do |header|
|
112
|
+
includes << "#include \"#{header}\""
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Include any user specified include files
|
117
|
+
def add_additional_includes
|
118
|
+
self.class.additional_includes.each do |inc|
|
119
|
+
includes << "#include \"#{inc}\""
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Set a list of user specified include files
|
124
|
+
def self.additional_includes=(addl)
|
125
|
+
@@additional_includes = addl
|
126
|
+
end
|
127
|
+
|
128
|
+
# Get an array of user specified include files
|
129
|
+
def self.additional_includes
|
130
|
+
@@additional_includes || []
|
131
|
+
end
|
132
|
+
|
133
|
+
# A list of all the source files. This is used in order to prevent files
|
134
|
+
# that are not in the list from being included and mucking things up
|
135
|
+
def self.sources=(sources)
|
136
|
+
@@sources = sources
|
137
|
+
end
|
138
|
+
|
139
|
+
# Retrieves a list of user specified source files
|
140
|
+
def self.sources
|
141
|
+
@@sources || []
|
57
142
|
end
|
58
143
|
|
59
144
|
# All builders must implement this method
|
@@ -64,7 +149,22 @@ module RbPlusPlus
|
|
64
149
|
# Builders should use to_s to make finishing touches on the generated
|
65
150
|
# code before it gets written out to a file.
|
66
151
|
def to_s
|
67
|
-
|
152
|
+
extras = []
|
153
|
+
#Weird trailing } needs to be destroyed!!!
|
154
|
+
if self.body.flatten[-1].strip == "}"
|
155
|
+
extras << self.body.delete_at(-1)
|
156
|
+
end
|
157
|
+
|
158
|
+
return [
|
159
|
+
self.includes.flatten.uniq,
|
160
|
+
"",
|
161
|
+
self.declarations,
|
162
|
+
"",
|
163
|
+
self.body,
|
164
|
+
"",
|
165
|
+
self.registered_nodes,
|
166
|
+
extras
|
167
|
+
].flatten.join("\n")
|
68
168
|
end
|
69
169
|
|
70
170
|
# Get the full qualified name of the related gccxml node
|
@@ -73,25 +173,37 @@ module RbPlusPlus
|
|
73
173
|
end
|
74
174
|
|
75
175
|
# Register all classes
|
76
|
-
def build_classes
|
77
|
-
@node.classes.
|
176
|
+
def build_classes(classes = nil)
|
177
|
+
classes ||= [@node.classes, @node.structs].flatten
|
178
|
+
classes.each do |klass|
|
179
|
+
next if klass.ignored? || klass.moved?
|
180
|
+
next unless klass.public?
|
78
181
|
builder = ClassBuilder.new(self, klass)
|
79
182
|
builder.build
|
80
183
|
builders << builder
|
81
184
|
end
|
82
185
|
end
|
83
186
|
|
187
|
+
# Find and wrap up all enumerations
|
188
|
+
def build_enumerations
|
189
|
+
@node.enumerations.each do |enum|
|
190
|
+
builder = EnumerationBuilder.new(self, enum)
|
191
|
+
builder.build
|
192
|
+
builders << builder
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
84
196
|
# Compatibility with Rice 1.0.1's explicit self requirement, build a quick
|
85
197
|
# wrapper that includes a self and discards it, forwarding the call as needed.
|
86
198
|
#
|
87
199
|
# Returns: the name of the wrapper function
|
88
|
-
def build_function_wrapper(function)
|
89
|
-
|
200
|
+
def build_function_wrapper(function, append="")
|
201
|
+
return if function.ignored? || function.moved?
|
202
|
+
wrapper_func = "wrap_#{function.qualified_name.gsub(/::/, "_")}#{append}"
|
90
203
|
|
91
204
|
proto_string = ["Rice::Object self"]
|
92
205
|
call_string = []
|
93
|
-
|
94
|
-
function.arguments.map{|arg| [arg.cpp_type.name, arg.name]}.each do |parts|
|
206
|
+
function.arguments.map{|arg| [arg.cpp_type.to_s(true), arg.name]}.each do |parts|
|
95
207
|
type = parts[0]
|
96
208
|
name = parts[1]
|
97
209
|
proto_string << "#{type} #{name}"
|
@@ -100,7 +212,7 @@ module RbPlusPlus
|
|
100
212
|
|
101
213
|
proto_string = proto_string.join(",")
|
102
214
|
call_string = call_string.join(",")
|
103
|
-
return_type = function.return_type.
|
215
|
+
return_type = function.return_type.to_s(true)
|
104
216
|
returns = "" if return_type == "void"
|
105
217
|
returns ||= "return"
|
106
218
|
|
@@ -111,6 +223,34 @@ module RbPlusPlus
|
|
111
223
|
wrapper_func
|
112
224
|
end
|
113
225
|
|
226
|
+
# Compatibility with Rice 1.0.1's method overloading issues. Build a quick
|
227
|
+
# wrapper that includes a self, forwarding the call as needed.
|
228
|
+
#
|
229
|
+
# Returns: the name of the wrapper function
|
230
|
+
def build_method_wrapper(cls, method, i)
|
231
|
+
return if method.ignored? || method.moved?
|
232
|
+
wrapper_func = "wrap_#{method.qualified_name.functionize}_#{i}"
|
233
|
+
proto_string = ["#{cls.qualified_name} *self"]
|
234
|
+
call_string = []
|
235
|
+
method.arguments.map{|arg| [arg.cpp_type.to_s(true), arg.name]}.each do |parts|
|
236
|
+
type = parts[0]
|
237
|
+
name = parts[1]
|
238
|
+
proto_string << "#{type} #{name}"
|
239
|
+
call_string << "#{name}"
|
240
|
+
end
|
241
|
+
|
242
|
+
proto_string = proto_string.join(",")
|
243
|
+
call_string = call_string.join(",")
|
244
|
+
return_type = method.return_type.to_s(true)
|
245
|
+
returns = "" if return_type == "void"
|
246
|
+
returns ||= "return"
|
247
|
+
|
248
|
+
declarations << "#{return_type} #{wrapper_func}(#{proto_string}) {"
|
249
|
+
declarations << "\t#{returns} self->#{method.qualified_name}(#{call_string});"
|
250
|
+
declarations << "}"
|
251
|
+
|
252
|
+
wrapper_func
|
253
|
+
end
|
114
254
|
end
|
115
255
|
end
|
116
256
|
end
|
@@ -11,52 +11,127 @@ module RbPlusPlus
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def build
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
|
15
|
+
#Handles templated super classes
|
16
|
+
@typedef_name = node.qualified_name.functionize
|
17
|
+
|
18
|
+
#Handles templated super classes passing in complex members
|
19
|
+
var_name = node.name
|
20
|
+
var_name.gsub!("::","_")
|
21
|
+
var_name.gsub!(/[ ,<>]/, "_")
|
22
|
+
var_name.gsub!("*", "Ptr")
|
23
|
+
|
24
|
+
self.rice_variable = "rb_c#{var_name}"
|
25
|
+
self.rice_variable_type = "Rice::Data_Type<#{self.qualified_name} >"
|
18
26
|
|
19
27
|
includes << "#include <rice/Class.hpp>"
|
20
28
|
includes << "#include <rice/Data_Type.hpp>"
|
21
|
-
includes << "#include <rice/Constructor.hpp>"
|
22
|
-
|
29
|
+
includes << "#include <rice/Constructor.hpp>"
|
30
|
+
|
31
|
+
add_additional_includes
|
32
|
+
add_includes_for node
|
33
|
+
|
34
|
+
self.declarations.insert(0,"typedef #{node.qualified_name} #{@typedef_name};")
|
35
|
+
|
36
|
+
@body << class_definition
|
37
|
+
|
38
|
+
@body += constructors
|
39
|
+
|
40
|
+
@body += methods
|
23
41
|
|
24
|
-
|
25
|
-
|
26
|
-
class_defn += "Rice::define_class_under<#{full_name}>(#{parent.rice_variable}, \"#{class_name}\");"
|
27
|
-
else
|
28
|
-
class_defn += "Rice::define_class<#{full_name}>(\"#{class_name}\");"
|
29
|
-
end
|
42
|
+
# Nested Classes
|
43
|
+
build_classes
|
30
44
|
|
31
|
-
|
45
|
+
# Enumerations
|
46
|
+
build_enumerations
|
47
|
+
end
|
32
48
|
|
49
|
+
# Build the constructors, and return an array of rice code
|
50
|
+
def constructors
|
51
|
+
result = []
|
52
|
+
# There are no constructors on purely virtual classes.
|
53
|
+
node.methods.each do |method|
|
54
|
+
next unless method.is_a? RbGCCXML::Method
|
55
|
+
return [] if method.purely_virtual?
|
56
|
+
end
|
33
57
|
# Constructors
|
34
58
|
node.constructors.each do |init|
|
35
|
-
|
36
|
-
|
59
|
+
next if init.ignored?
|
60
|
+
next unless init.public?
|
61
|
+
args = [@typedef_name, init.arguments.map {|a| a.cpp_type.to_s(true) }].flatten
|
62
|
+
result << "\t#{rice_variable}.define_constructor(Rice::Constructor<#{args.join(",")}>());"
|
37
63
|
end
|
38
|
-
|
39
|
-
|
64
|
+
result
|
65
|
+
end
|
66
|
+
|
67
|
+
# Build the methods, and return an array of rice code
|
68
|
+
def methods
|
69
|
+
result = []
|
70
|
+
# Methods are thrown into a hash table so that we can
|
71
|
+
# determine overloaded methods
|
72
|
+
methods_hash = {}
|
40
73
|
node.methods.each do |method|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
74
|
+
next unless method.public?
|
75
|
+
|
76
|
+
methods_hash[method.qualified_name] ||= []
|
77
|
+
methods_hash[method.qualified_name] << method
|
78
|
+
end
|
79
|
+
|
80
|
+
methods_hash.each do |key, methods|
|
81
|
+
#Add any method with a const return type to the typemanager
|
82
|
+
methods.each do |method|
|
83
|
+
next if method.ignored? || method.moved?
|
84
|
+
if method.return_type.const? || method.const?
|
85
|
+
TypesManager.build_const_converter(method.return_type)
|
86
|
+
end
|
47
87
|
end
|
88
|
+
#No overloaded methods
|
89
|
+
if methods.length == 1
|
90
|
+
method = methods[0]
|
91
|
+
next if method.ignored? || method.moved?
|
92
|
+
m = "define_method"
|
93
|
+
name = method.qualified_name
|
48
94
|
|
49
|
-
|
50
|
-
|
95
|
+
if method.static?
|
96
|
+
m = "define_singleton_method"
|
97
|
+
name = build_function_wrapper(method)
|
98
|
+
end
|
51
99
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
100
|
+
result << "\t#{rice_variable}.#{m}(\"#{Inflector.underscore(method.name)}\", &#{name});"
|
101
|
+
else
|
102
|
+
#Handle overloaded methods
|
103
|
+
#currently we just append an index to them if they have not been renamed
|
104
|
+
#for example getOrigin() and getOrigin(x,y) become
|
105
|
+
#get_origin_0 and get_origin_1
|
106
|
+
methods.each_with_index do |method, i|
|
107
|
+
next if method.ignored? || method.moved?
|
108
|
+
name = build_method_wrapper(node, method, i)
|
109
|
+
m = "define_method"
|
110
|
+
method_name = "#{Inflector.underscore(method.name)}"
|
111
|
+
method_name += "_#{i}" unless method.renamed?
|
112
|
+
result << "\t#{rice_variable}.#{m}(\"#{method_name}\", &#{name});"
|
113
|
+
end
|
114
|
+
end
|
57
115
|
end
|
116
|
+
result
|
117
|
+
end
|
118
|
+
|
119
|
+
# Return a rice string representing Rice's class definition.
|
120
|
+
def class_definition
|
121
|
+
class_defn = "\t#{rice_variable_type} #{rice_variable} = "
|
122
|
+
|
123
|
+
class_name = node.name
|
124
|
+
supers = node.super_classes.collect { |s| s.qualified_name }
|
125
|
+
class_names = [@typedef_name, supers].flatten.join(",")
|
126
|
+
|
127
|
+
if !parent.is_a?(ExtensionBuilder)
|
128
|
+
class_defn += "Rice::define_class_under<#{class_names} >(#{parent.rice_variable}, \"#{class_name}\");"
|
129
|
+
else
|
130
|
+
class_defn += "Rice::define_class<#{class_names} >(\"#{class_name}\");"
|
131
|
+
end
|
132
|
+
class_defn
|
58
133
|
end
|
59
|
-
|
60
134
|
end
|
135
|
+
|
61
136
|
end
|
62
137
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RbPlusPlus
|
2
|
+
module Builders
|
3
|
+
|
4
|
+
# This class handles generating source for a requested Module
|
5
|
+
class EnumerationBuilder < Base
|
6
|
+
|
7
|
+
# Different initializer to keep things clean
|
8
|
+
def initialize(parent, node)
|
9
|
+
super(node.name, node)
|
10
|
+
self.parent = parent
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
includes << "#include <rice/Enum.hpp>"
|
15
|
+
enum_name = node.name
|
16
|
+
full_name = node.qualified_name
|
17
|
+
self.rice_variable = "rb_e#{enum_name}"
|
18
|
+
self.rice_variable_type = "Rice::Enum<#{full_name}>"
|
19
|
+
|
20
|
+
add_additional_includes
|
21
|
+
|
22
|
+
defn = "\t#{rice_variable_type} #{rice_variable} = "
|
23
|
+
|
24
|
+
second_arg = ""
|
25
|
+
if !parent.is_a?(ExtensionBuilder)
|
26
|
+
second_arg = ", #{parent.rice_variable}"
|
27
|
+
end
|
28
|
+
|
29
|
+
defn += "Rice::define_enum<#{full_name}>(\"#{enum_name}\" #{second_arg});"
|
30
|
+
|
31
|
+
body << defn
|
32
|
+
|
33
|
+
node.values.each do |v|
|
34
|
+
body << "\t#{rice_variable}.define_value(\"#{v.name}\", #{v.to_s(true)});"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -11,17 +11,43 @@ module RbPlusPlus
|
|
11
11
|
def build
|
12
12
|
includes << "#include <rice/global_function.hpp>"
|
13
13
|
|
14
|
+
add_additional_includes
|
15
|
+
|
14
16
|
body << "extern \"C\""
|
15
17
|
body << "void Init_#{@name}() {"
|
16
18
|
|
17
19
|
# Explicitly ignore anything from the :: namespace
|
18
20
|
if @node.name != "::"
|
21
|
+
|
22
|
+
#Build a hash table to handle overloaded functions
|
23
|
+
func_hash = {}
|
19
24
|
@node.functions.each do |func|
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
next if func.ignored? || func.moved?
|
26
|
+
|
27
|
+
func_hash[func.name] ||= []
|
28
|
+
func_hash[func.name] << func
|
23
29
|
end
|
30
|
+
#Iterate through the hash table to handle overloaded functions
|
31
|
+
func_hash.each do |key, funcs|
|
32
|
+
funcs.each_with_index do |func, i|
|
33
|
+
add_includes_for func
|
34
|
+
|
35
|
+
#append _#{i} to overloaded methods
|
36
|
+
#this needs to be done in both the wrapper function and the ruby function
|
37
|
+
func_append = ""
|
38
|
+
func_append = "_#{i}" if funcs.size > 1
|
39
|
+
wrapper_name = func.special_qualified_name || build_function_wrapper(func, func_append)
|
40
|
+
|
41
|
+
if func.return_type.const? || func.const?
|
42
|
+
TypesManager.build_const_converter(func.return_type)
|
43
|
+
end
|
24
44
|
|
45
|
+
ruby_name = "#{Inflector.underscore(func.name)}#{func_append}"
|
46
|
+
body << "\tdefine_global_function(\"#{ruby_name}\", &#{wrapper_name});"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
build_enumerations
|
25
51
|
build_classes
|
26
52
|
end
|
27
53
|
|
@@ -39,9 +65,8 @@ module RbPlusPlus
|
|
39
65
|
# Finish up the required code before doing final output
|
40
66
|
def to_s
|
41
67
|
includes << "using namespace Rice;"
|
42
|
-
|
43
|
-
|
44
|
-
super
|
68
|
+
|
69
|
+
super + "\n}"
|
45
70
|
end
|
46
71
|
end
|
47
72
|
end
|
@@ -18,6 +18,8 @@ module RbPlusPlus
|
|
18
18
|
self.rice_variable_type = "Rice::Module"
|
19
19
|
|
20
20
|
includes << "#include <rice/Module.hpp>"
|
21
|
+
|
22
|
+
add_additional_includes
|
21
23
|
|
22
24
|
mod_defn = "\t#{rice_variable_type} #{rice_variable} = "
|
23
25
|
if !parent.is_a?(ExtensionBuilder)
|
@@ -29,11 +31,14 @@ module RbPlusPlus
|
|
29
31
|
body << mod_defn
|
30
32
|
|
31
33
|
# If a namespace has been given to this module, find and wrap the appropriate code
|
32
|
-
if
|
33
|
-
|
34
|
-
build_classes
|
34
|
+
if self.node
|
35
|
+
build_enumerations
|
35
36
|
end
|
36
37
|
|
38
|
+
build_functions unless @module.functions.empty?
|
39
|
+
build_classes(@module.classes) unless @module.classes.empty?
|
40
|
+
|
41
|
+
|
37
42
|
# Build each inner module
|
38
43
|
@module.modules.each do |mod|
|
39
44
|
builder = ModuleBuilder.new(self, mod)
|
@@ -44,11 +49,12 @@ module RbPlusPlus
|
|
44
49
|
|
45
50
|
# Process functions to be added to this module
|
46
51
|
def build_functions
|
47
|
-
@
|
48
|
-
|
52
|
+
@module.functions.each do |func|
|
53
|
+
next if func.ignored? || func.moved? # fine grained function filtering
|
54
|
+
add_includes_for func
|
49
55
|
|
50
56
|
func_name = Inflector.underscore(func.name)
|
51
|
-
wrapped_name = build_function_wrapper(func)
|
57
|
+
wrapped_name = func.special_qualified_name || build_function_wrapper(func)
|
52
58
|
body << "\t#{self.rice_variable}.define_module_function(\"#{func_name}\", &#{wrapped_name});"
|
53
59
|
end
|
54
60
|
end
|