rbind 0.0.1
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/lib/rbind.rb +5 -0
- data/lib/rbind/.default_parser.rb.swp +0 -0
- data/lib/rbind/.generator_c.rb.swp +0 -0
- data/lib/rbind/core.rb +13 -0
- data/lib/rbind/core/.rbase.rb.swp +0 -0
- data/lib/rbind/core/.rclass.rb.swp +0 -0
- data/lib/rbind/core/.rdata_type.rb.swp +0 -0
- data/lib/rbind/core/.roperation.rb.swp +0 -0
- data/lib/rbind/core/rattribute.rb +45 -0
- data/lib/rbind/core/rbase.rb +172 -0
- data/lib/rbind/core/rclass.rb +149 -0
- data/lib/rbind/core/rconst.rb +35 -0
- data/lib/rbind/core/rdata_type.rb +93 -0
- data/lib/rbind/core/renum.rb +5 -0
- data/lib/rbind/core/rgetter.rb +19 -0
- data/lib/rbind/core/rnamespace.rb +305 -0
- data/lib/rbind/core/roperation.rb +128 -0
- data/lib/rbind/core/rparameter.rb +40 -0
- data/lib/rbind/core/rsetter.rb +20 -0
- data/lib/rbind/core/rstruct.rb +87 -0
- data/lib/rbind/default_parser.rb +253 -0
- data/lib/rbind/generator_c.rb +352 -0
- data/lib/rbind/generator_ruby.rb +357 -0
- data/lib/rbind/logger.rb +13 -0
- data/lib/rbind/rbind.rb +68 -0
- data/lib/rbind/templates/c/CMakeLists.txt +11 -0
- data/lib/rbind/templates/c/consts.h +5 -0
- data/lib/rbind/templates/c/conversions.cc +4 -0
- data/lib/rbind/templates/c/conversions.hpp +10 -0
- data/lib/rbind/templates/c/find_package.txt +5 -0
- data/lib/rbind/templates/c/operation_wrapper.cc +15 -0
- data/lib/rbind/templates/c/operations.cc +23 -0
- data/lib/rbind/templates/c/operations.h +20 -0
- data/lib/rbind/templates/c/type_conversion.cc +45 -0
- data/lib/rbind/templates/c/type_conversion.hpp +5 -0
- data/lib/rbind/templates/c/type_delete.h +14 -0
- data/lib/rbind/templates/c/type_typedef.h +2 -0
- data/lib/rbind/templates/c/type_wrapper.h +12 -0
- data/lib/rbind/templates/c/types.cc +6 -0
- data/lib/rbind/templates/c/types.h +17 -0
- data/lib/rbind/templates/ruby/rbind.rb +44 -0
- data/lib/rbind/templates/ruby/rmethod.rb +12 -0
- data/lib/rbind/templates/ruby/rnamespace.rb +7 -0
- data/lib/rbind/templates/ruby/rstatic_method.rb +5 -0
- data/lib/rbind/templates/ruby/rtype.rb +77 -0
- data/lib/rbind/templates/ruby/rtype_constructor.rb +4 -0
- data/rbind.gemspec +17 -0
- metadata +101 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module Rbind
|
3
|
+
class RParameter < RAttribute
|
4
|
+
attr_accessor :default_value
|
5
|
+
|
6
|
+
def initialize(name,type,default_value=nil,*flags)
|
7
|
+
super(name,type,*flags)
|
8
|
+
self.default_value = default_value
|
9
|
+
end
|
10
|
+
|
11
|
+
def default_value=(val)
|
12
|
+
@default_value = if val && !val.empty?
|
13
|
+
val.chomp.chomp(" ")
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_value(val = nil)
|
20
|
+
if val
|
21
|
+
self.default_value = val
|
22
|
+
self
|
23
|
+
else
|
24
|
+
@default_value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_flags
|
29
|
+
[:IO,:O]
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_signatures
|
33
|
+
c,cs = super
|
34
|
+
if default_value
|
35
|
+
c = "#{c}=#{default_value}"
|
36
|
+
end
|
37
|
+
[c,cs]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module Rbind
|
3
|
+
class RSetter < ROperation
|
4
|
+
attr_reader :attribute
|
5
|
+
|
6
|
+
def initialize(attr)
|
7
|
+
@attribute = attr
|
8
|
+
para = RParameter.new("value",attr.type)
|
9
|
+
super("set_#{attr.name}",RDataType.new("void"),para)
|
10
|
+
end
|
11
|
+
|
12
|
+
def attribute?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def signature
|
17
|
+
attribute.signature
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
|
2
|
+
module Rbind
|
3
|
+
class RStruct < RNamespace
|
4
|
+
attr_reader :attributes
|
5
|
+
|
6
|
+
def initialize(name,*flags)
|
7
|
+
@attributes = Hash.new
|
8
|
+
super(name,*flags)
|
9
|
+
end
|
10
|
+
|
11
|
+
def basic_type?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_flags
|
16
|
+
super << :Simple << :Map
|
17
|
+
end
|
18
|
+
|
19
|
+
def constructor?
|
20
|
+
ops = Array(operation(name,false))
|
21
|
+
return false unless ops
|
22
|
+
op = ops.find do |op|
|
23
|
+
op.constructor?
|
24
|
+
end
|
25
|
+
!!op
|
26
|
+
end
|
27
|
+
|
28
|
+
def attributes
|
29
|
+
@attributes.values
|
30
|
+
end
|
31
|
+
|
32
|
+
def attribute(name)
|
33
|
+
@attributes[name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def cdelete_method
|
37
|
+
if @cdelete_method
|
38
|
+
@cdelete_method
|
39
|
+
else
|
40
|
+
if cname =~ /^#{RBase.cprefix}(.*)/
|
41
|
+
"#{RBase.cprefix}delete_#{$1}"
|
42
|
+
else
|
43
|
+
"#{RBase.cprefix}delete_#{name}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_attribute(attr)
|
49
|
+
if attr.namespace?
|
50
|
+
type(attr.namespace).add_attribute(attr)
|
51
|
+
else
|
52
|
+
if @attributes.has_key? attr.name
|
53
|
+
raise "#An attribute with the name #{attr.name} already exists"
|
54
|
+
end
|
55
|
+
attr.owner = self
|
56
|
+
@attributes[attr.name] = attr
|
57
|
+
# add getter and setter methods to the object
|
58
|
+
add_operation(RGetter.new(attr))
|
59
|
+
add_operation(RSetter.new(attr)) if attr.write?
|
60
|
+
end
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def pretty_print_name
|
65
|
+
"struct #{full_name}#{" Flags: #{flags.join(", ")}" unless flags.empty?}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def pretty_print(pp)
|
69
|
+
super
|
70
|
+
unless attributes.empty?
|
71
|
+
pp.nest(2) do
|
72
|
+
pp.breakable
|
73
|
+
pp.text "Attributes:"
|
74
|
+
pp.nest(2) do
|
75
|
+
attributes.each do |a|
|
76
|
+
pp.breakable
|
77
|
+
pp.pp(a)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
@@ -0,0 +1,253 @@
|
|
1
|
+
|
2
|
+
module Rbind
|
3
|
+
class DefaultParser < RNamespace
|
4
|
+
extend ::Rbind::Logger
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
super("root")
|
8
|
+
self.root = true
|
9
|
+
add_default_types
|
10
|
+
@on_type_not_found
|
11
|
+
end
|
12
|
+
|
13
|
+
def normalize_flags(line_number,flags)
|
14
|
+
flags.map do |flag|
|
15
|
+
if flag =~ /(\w*)(.*)/
|
16
|
+
DefaultParser.log.info "input line #{line_number}: ignoring flag #{$2}" unless $2.empty?
|
17
|
+
$1.to_sym
|
18
|
+
else
|
19
|
+
raise "cannot parse flag #{flag.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def normalize_default_value(value)
|
25
|
+
val = value.gsub(/(.?)std::vector<(.*)>/,'\1vector_\2')
|
26
|
+
if value != val
|
27
|
+
normalize_default_value(val)
|
28
|
+
else
|
29
|
+
val
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_data_type_name(name)
|
34
|
+
t = RDataType.new(name)
|
35
|
+
add_type t
|
36
|
+
t
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_namespace_name(name)
|
40
|
+
ns = RNamespace.new(name)
|
41
|
+
add_type ns
|
42
|
+
ns
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_struct_name(name)
|
46
|
+
s = RStruct.new(name)
|
47
|
+
add_type s
|
48
|
+
s
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_class_name(name)
|
52
|
+
klass = RClass.new(name)
|
53
|
+
add_type klass
|
54
|
+
klass
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_type_not_found(&block)
|
58
|
+
@on_type_not_found = block
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def find_type(owner,type_name)
|
63
|
+
t = owner.type(type_name,false)
|
64
|
+
return t if t
|
65
|
+
|
66
|
+
normalized = type_name.split("_")
|
67
|
+
name = normalized.shift
|
68
|
+
while !normalized.empty?
|
69
|
+
name += "::#{normalized.shift}"
|
70
|
+
t = if normalized.empty?
|
71
|
+
owner.type(name,false)
|
72
|
+
else
|
73
|
+
owner.type("#{name}_#{normalized.join("_")}",false)
|
74
|
+
end
|
75
|
+
return t if t
|
76
|
+
end
|
77
|
+
t = @on_type_not_found.call(owner,type_name) if @on_type_not_found
|
78
|
+
return t if t
|
79
|
+
|
80
|
+
#search again even if we know the type is not there to create a proper error message
|
81
|
+
owner.type(type_name,true)
|
82
|
+
end
|
83
|
+
|
84
|
+
def parameter(line_number,string,owner = self)
|
85
|
+
flags = string.split(" /")
|
86
|
+
array = flags.shift.split(" ")
|
87
|
+
type_name = array.shift
|
88
|
+
para_name = array.shift
|
89
|
+
default = normalize_default_value(array.join(" "))
|
90
|
+
type = find_type(owner,type_name)
|
91
|
+
flags = normalize_flags(line_number,flags)
|
92
|
+
RParameter.new(para_name,type,default,flags)
|
93
|
+
rescue RuntimeError => e
|
94
|
+
raise "input line #{line_number}: #{e}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def attribute(line_number,string,owner=self)
|
98
|
+
flags = string.split(" /")
|
99
|
+
array = flags.shift.split(" ")
|
100
|
+
type_name = array[0]
|
101
|
+
name = array[1]
|
102
|
+
type = find_type(owner,type_name)
|
103
|
+
flags = normalize_flags(line_number,flags)
|
104
|
+
RAttribute.new(name,type,flags)
|
105
|
+
rescue RuntimeError => e
|
106
|
+
raise "input line #{line_number}: #{e}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def parse_class(line_number,string)
|
110
|
+
lines = string.split("\n")
|
111
|
+
a = lines.shift.rstrip.split(" : ")
|
112
|
+
name = a[0].split(" ")[1]
|
113
|
+
parents = a[1]
|
114
|
+
parent_classes = if parents
|
115
|
+
parents.split(", ").map do |name|
|
116
|
+
type(RBase.normalize(name),true)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
t = RClass.new(name,*parent_classes)
|
120
|
+
t = if t2 = type(t.full_name,false)
|
121
|
+
if !t2.is_a?(RClass) || (!t2.parent_classes.empty? && t2.parent_classes != t.parent_classes)
|
122
|
+
raise "Cannot add class #{t.full_name}. A different type #{t2} is already registered"
|
123
|
+
else
|
124
|
+
t2.parent_classes = t.instance_variable_get(:@parent_classes)
|
125
|
+
t2
|
126
|
+
end
|
127
|
+
else
|
128
|
+
add_type(t)
|
129
|
+
t
|
130
|
+
end
|
131
|
+
line_counter = 1
|
132
|
+
lines.each do |line|
|
133
|
+
a = attribute(line_counter+line_number,line,t)
|
134
|
+
t.add_attribute(a)
|
135
|
+
line_counter += 1
|
136
|
+
end
|
137
|
+
[t,line_counter]
|
138
|
+
rescue RuntimeError => e
|
139
|
+
raise "input line #{line_number}: #{e}"
|
140
|
+
end
|
141
|
+
|
142
|
+
def parse_struct(line_number,string)
|
143
|
+
a = string.split("\n")
|
144
|
+
first_line = a.shift
|
145
|
+
flags = first_line.split(" /")
|
146
|
+
name = flags.shift.split(" ")[1]
|
147
|
+
flags = normalize_flags(line_number,flags)
|
148
|
+
klass = RStruct.new(name,flags)
|
149
|
+
add_type(klass)
|
150
|
+
line_counter = 1
|
151
|
+
a.each do |line|
|
152
|
+
a = attribute(line_counter+line_number,line,klass)
|
153
|
+
klass.add_attribute(a)
|
154
|
+
line_counter += 1
|
155
|
+
end
|
156
|
+
[klass,line_counter]
|
157
|
+
rescue RuntimeError => e
|
158
|
+
raise "input line #{line_number}: #{e}"
|
159
|
+
end
|
160
|
+
|
161
|
+
def parse_const(line_number,string)
|
162
|
+
raise "multi line const are not supported: #{string}" if string.split("\n").size > 1
|
163
|
+
a = string.split(" ")
|
164
|
+
raise "not a constant: #{string}" unless a.shift == "const"
|
165
|
+
name = a.shift
|
166
|
+
value = a.join(" ")
|
167
|
+
c = RConst.new(name,value)
|
168
|
+
add_const(c)
|
169
|
+
[c,1]
|
170
|
+
end
|
171
|
+
|
172
|
+
def parse_operation(line_number,string)
|
173
|
+
a = string.split("\n")
|
174
|
+
line = a.shift
|
175
|
+
flags = line.split(" /")
|
176
|
+
line = flags.shift
|
177
|
+
elements = line.split(" ")
|
178
|
+
name = elements.shift
|
179
|
+
return_type_name = elements.shift
|
180
|
+
if return_type_name == "()"
|
181
|
+
name += return_type_name
|
182
|
+
return_type_name = elements.shift
|
183
|
+
end
|
184
|
+
alias_name = elements.shift
|
185
|
+
alias_name = if alias_name
|
186
|
+
raise "#{line_number}: cannot parse #{string}" unless alias_name =~/^=.*/
|
187
|
+
alias_name.gsub("=","")
|
188
|
+
end
|
189
|
+
|
190
|
+
ns = RBase.namespace(name)
|
191
|
+
owner = type(ns,true)
|
192
|
+
if return_type_name == "explicit"
|
193
|
+
flags << return_type_name
|
194
|
+
return_type_name = nil
|
195
|
+
end
|
196
|
+
return_type = if return_type_name && !return_type_name.empty?
|
197
|
+
find_type(owner,return_type_name)
|
198
|
+
end
|
199
|
+
line_counter = 1
|
200
|
+
args = a.map do |line|
|
201
|
+
p = parameter(line_number+line_counter,line,owner)
|
202
|
+
line_counter += 1
|
203
|
+
p
|
204
|
+
end
|
205
|
+
op = ::Rbind::ROperation.new(name,return_type,*args)
|
206
|
+
op.alias = alias_name if alias_name && !alias_name.empty?
|
207
|
+
op.flags = normalize_flags(line_number,flags)
|
208
|
+
type(op.namespace,true).add_operation(op)
|
209
|
+
[op,line_counter]
|
210
|
+
end
|
211
|
+
|
212
|
+
def parse(string)
|
213
|
+
a = split(string)
|
214
|
+
a.pop #remove number at the end of the file
|
215
|
+
line_number = 1
|
216
|
+
a.each do |block|
|
217
|
+
begin
|
218
|
+
first = block.split(" ",2)[0]
|
219
|
+
obj,lines = if first == "const"
|
220
|
+
parse_const(line_number,block)
|
221
|
+
elsif first == "class"
|
222
|
+
parse_class(line_number,block)
|
223
|
+
elsif first == "struct"
|
224
|
+
parse_struct(line_number,block)
|
225
|
+
else
|
226
|
+
parse_operation(line_number,block)
|
227
|
+
end
|
228
|
+
line_number+=lines
|
229
|
+
rescue RuntimeError => e
|
230
|
+
puts "Parsing Error: #{e}"
|
231
|
+
puts "Line #{line_number}:"
|
232
|
+
puts "--------------------------------------------------"
|
233
|
+
puts block
|
234
|
+
puts "--------------------------------------------------"
|
235
|
+
Kernel.raise
|
236
|
+
break
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def split(string)
|
242
|
+
array = []
|
243
|
+
string.each_line do |line|
|
244
|
+
if !line.empty? && line[0] != " "
|
245
|
+
array << line
|
246
|
+
else
|
247
|
+
array[array.size-1] = array.last + line
|
248
|
+
end
|
249
|
+
end
|
250
|
+
array
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'delegate'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Rbind
|
6
|
+
class GeneratorC
|
7
|
+
|
8
|
+
class HelperBase
|
9
|
+
attr_accessor :includes
|
10
|
+
attr_accessor :name
|
11
|
+
|
12
|
+
def initialize(name,root)
|
13
|
+
@root = root
|
14
|
+
@name = name
|
15
|
+
@includes = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def wrap_includes
|
19
|
+
includes.map do |i|
|
20
|
+
if i =~ /<.*>/
|
21
|
+
"#include #{i}"
|
22
|
+
else
|
23
|
+
"#include \"#{i}\""
|
24
|
+
end
|
25
|
+
end.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def binding
|
29
|
+
Kernel.binding
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class TypesHelperHDR < HelperBase
|
34
|
+
def initialize(name, root)
|
35
|
+
raise "wrong type #{root}" unless root.is_a? RDataType
|
36
|
+
super
|
37
|
+
@type_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","type_wrapper.h")).read,nil,"-")
|
38
|
+
end
|
39
|
+
|
40
|
+
def cdelete_method
|
41
|
+
@root.cdelete_method
|
42
|
+
end
|
43
|
+
|
44
|
+
def type_wrapper(t)
|
45
|
+
@type_wrapper.result(t.binding)
|
46
|
+
end
|
47
|
+
|
48
|
+
def wrap_types
|
49
|
+
str = ""
|
50
|
+
@root.each_type do |type|
|
51
|
+
next if type.basic_type?
|
52
|
+
str += type_wrapper(type)
|
53
|
+
end
|
54
|
+
str
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class TypesHelper < HelperBase
|
59
|
+
def initialize(name, root)
|
60
|
+
super
|
61
|
+
@type_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","type_delete.h")).read)
|
62
|
+
end
|
63
|
+
|
64
|
+
def cdelete_method
|
65
|
+
@root.cdelete_method
|
66
|
+
end
|
67
|
+
|
68
|
+
def type_wrapper(t)
|
69
|
+
@type_wrapper.result(t.binding)
|
70
|
+
end
|
71
|
+
|
72
|
+
def wrap_types
|
73
|
+
str = ""
|
74
|
+
@root.each_type do |type|
|
75
|
+
next if type.basic_type?
|
76
|
+
str += type_wrapper(type)
|
77
|
+
end
|
78
|
+
str
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class ConstsHelper < HelperBase
|
83
|
+
def wrap_consts
|
84
|
+
str = ""
|
85
|
+
@root.each_type do |type|
|
86
|
+
next if !type.container?
|
87
|
+
next if type.consts.empty?
|
88
|
+
str += "\n\n//constants for #{type.full_name}\n"
|
89
|
+
str += type.consts.map do |c|
|
90
|
+
"#{c.csignature};\n"
|
91
|
+
end.join
|
92
|
+
str
|
93
|
+
end
|
94
|
+
str
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class ConversionsHelperHDR < HelperBase
|
99
|
+
def initialize(name,root)
|
100
|
+
super
|
101
|
+
@type_conversion = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","type_conversion.hpp")).read,nil,'-')
|
102
|
+
@type_typedef = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","type_typedef.h")).read)
|
103
|
+
end
|
104
|
+
|
105
|
+
def type_conversion(t)
|
106
|
+
@type_conversion.result(t.binding)
|
107
|
+
end
|
108
|
+
|
109
|
+
def type_typedef(t)
|
110
|
+
@type_typedef.result(t.binding)
|
111
|
+
end
|
112
|
+
|
113
|
+
def wrap_conversions
|
114
|
+
str = ""
|
115
|
+
@root.each_type do |type|
|
116
|
+
str += type_typedef(type) if type.typedef?
|
117
|
+
next if type.basic_type?
|
118
|
+
str += type_conversion(type)
|
119
|
+
end
|
120
|
+
str
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class ConversionsHelper < HelperBase
|
125
|
+
def initialize(name,root)
|
126
|
+
super
|
127
|
+
@type_conversion = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","type_conversion.cc")).read,nil,'-')
|
128
|
+
end
|
129
|
+
|
130
|
+
def type_conversion(t)
|
131
|
+
@type_conversion.result(t.binding)
|
132
|
+
end
|
133
|
+
|
134
|
+
def check_type?
|
135
|
+
type_check?
|
136
|
+
end
|
137
|
+
|
138
|
+
def wrap_conversions
|
139
|
+
str = ""
|
140
|
+
@root.each_type do |type|
|
141
|
+
next if type.basic_type?
|
142
|
+
str += type_conversion(type)
|
143
|
+
end
|
144
|
+
str
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class OperationsHDRHelper < HelperBase
|
149
|
+
def initialize(name,root)
|
150
|
+
super
|
151
|
+
end
|
152
|
+
|
153
|
+
def wrap_operations
|
154
|
+
str = ""
|
155
|
+
@root.each_type do |type|
|
156
|
+
next unless type.respond_to? :operations
|
157
|
+
str2 = type.operations.map do |ops|
|
158
|
+
ops.map do |op|
|
159
|
+
"#{op.csignature};"
|
160
|
+
end.join("\n")
|
161
|
+
end.join("\n")
|
162
|
+
if !str2.empty?
|
163
|
+
str += "\n\n///methods for #{type.full_name}\n"
|
164
|
+
str += str2
|
165
|
+
end
|
166
|
+
end
|
167
|
+
str
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
class OperationsHelper < HelperBase
|
172
|
+
class OperationHelper < SimpleDelegator
|
173
|
+
def wrap_parameters
|
174
|
+
cparameters.map do |arg|
|
175
|
+
next if arg.type.basic_type?
|
176
|
+
"#{"const " if arg.read_only?}#{arg.type.full_name} *#{arg.name}_ = fromC(#{arg.name});\n\t"
|
177
|
+
end.compact.join("")
|
178
|
+
end
|
179
|
+
|
180
|
+
def wrap_call
|
181
|
+
paras = parameters.map do |arg|
|
182
|
+
"#{"*" if (!arg.type.ptr? && !arg.type.basic_type?)}#{arg.name}#{"_" if !arg.type.basic_type?}"
|
183
|
+
end.join(", ")
|
184
|
+
fct = if attribute?
|
185
|
+
if return_type.name == "void" && !return_type.ptr?
|
186
|
+
"rbind_obj_->#{attribute.name} = #{paras};"
|
187
|
+
else
|
188
|
+
if return_type.basic_type?
|
189
|
+
"return rbind_obj_->#{attribute.name};"
|
190
|
+
elsif return_type.ptr?
|
191
|
+
"return toC(rbind_obj_->#{attribute.name},false);"
|
192
|
+
else
|
193
|
+
"return toC(&rbind_obj_->#{attribute.name},false);"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
else
|
197
|
+
fct = if !constructor? && (return_type.name != "void" || return_type.ptr?)
|
198
|
+
if operator? && parameters.size == 1
|
199
|
+
if return_type.basic_type?
|
200
|
+
"return *rbind_obj_ #{operator} #{paras};"
|
201
|
+
else
|
202
|
+
"return toC(new #{return_type.full_name}(*rbind_obj_ #{operator} #{paras}));"
|
203
|
+
end
|
204
|
+
elsif return_type.basic_type?
|
205
|
+
"return #{full_name}(#{paras});"
|
206
|
+
elsif return_type.ptr?
|
207
|
+
"return toC(#{full_name}(#{paras}));"
|
208
|
+
else
|
209
|
+
"return toC(new #{return_type.full_name}(#{full_name}(#{paras})));"
|
210
|
+
end
|
211
|
+
else
|
212
|
+
if constructor?
|
213
|
+
"return toC(new #{namespace}(#{paras}));"
|
214
|
+
else
|
215
|
+
if operator?
|
216
|
+
"*rbind_obj_ #{operator} #{paras};"
|
217
|
+
else
|
218
|
+
"#{full_name}(#{paras});"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
#convert call to member call
|
223
|
+
if instance_method?
|
224
|
+
#add base class name space
|
225
|
+
if((inherit? && !abstract?) || ambiguous_name?)
|
226
|
+
fct.gsub(full_name,"rbind_obj_->#{base_class.name}::#{name}")
|
227
|
+
else
|
228
|
+
fct.gsub(full_name,"rbind_obj_->#{name}")
|
229
|
+
end
|
230
|
+
else
|
231
|
+
fct
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def binding
|
237
|
+
Kernel.binding
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
def initialize(name,root)
|
243
|
+
super
|
244
|
+
@operation_wrapper = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","operation_wrapper.cc")).read,nil,"-")
|
245
|
+
end
|
246
|
+
|
247
|
+
def operation_wrapper(op)
|
248
|
+
raise unless op
|
249
|
+
op2 = OperationHelper.new(op)
|
250
|
+
@operation_wrapper.result(op2.binding)
|
251
|
+
end
|
252
|
+
|
253
|
+
def wrap_operations
|
254
|
+
str = ""
|
255
|
+
@root.each_type do |type|
|
256
|
+
next unless type.respond_to? :operations
|
257
|
+
str += type.operations.map do |ops|
|
258
|
+
ops.map do |op|
|
259
|
+
operation_wrapper(op)
|
260
|
+
end.join("\n")
|
261
|
+
end.join("\n")
|
262
|
+
end
|
263
|
+
str
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
class CMakeListsHelper < HelperBase
|
268
|
+
def initialize(name,pkg_config=Array.new)
|
269
|
+
super
|
270
|
+
@find_package = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","find_package.txt")).read)
|
271
|
+
end
|
272
|
+
|
273
|
+
def find_packages
|
274
|
+
@root.map do |pkg|
|
275
|
+
@find_package.result(pkg.instance_eval("binding"))
|
276
|
+
end.join("")
|
277
|
+
end
|
278
|
+
|
279
|
+
def libs
|
280
|
+
@root.map do |pkg|
|
281
|
+
"${#{pkg.upcase}_LIBS} ${#{pkg.upcase}_LDFLAGS}"
|
282
|
+
end.join(" ")
|
283
|
+
end
|
284
|
+
|
285
|
+
def library_name
|
286
|
+
name
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
attr_accessor :includes
|
291
|
+
attr_accessor :library_name
|
292
|
+
attr_accessor :pkg_config
|
293
|
+
attr_accessor :generate_cmake
|
294
|
+
|
295
|
+
def initialize(root,library_name)
|
296
|
+
raise "wrong type #{root}" unless root.is_a? RNamespace
|
297
|
+
@root = root
|
298
|
+
@erb_types_hdr = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","types.h")).read)
|
299
|
+
@erb_types = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","types.cc")).read)
|
300
|
+
@erb_consts = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","consts.h")).read)
|
301
|
+
@erb_operations = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","operations.cc")).read)
|
302
|
+
@erb_operations_hdr = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","operations.h")).read)
|
303
|
+
@erb_conversions = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","conversions.cc")).read)
|
304
|
+
@erb_conversions_hdr = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","conversions.hpp")).read)
|
305
|
+
@erb_cmakelists = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","CMakeLists.txt")).read)
|
306
|
+
@erb_find_package = ERB.new(File.open(File.join(File.dirname(__FILE__),"templates","c","find_package.txt")).read)
|
307
|
+
@includes = Array.new
|
308
|
+
@pkgconfig= Array.new
|
309
|
+
@library_name = library_name
|
310
|
+
@generate_cmake = true
|
311
|
+
end
|
312
|
+
|
313
|
+
def generate(path = nil)
|
314
|
+
FileUtils.mkdir_p(path) if path && !File.directory?(path)
|
315
|
+
file_types_hdr = File.new(File.join(path,"types.h"),"w")
|
316
|
+
file_types = File.new(File.join(path,"types.cc"),"w")
|
317
|
+
file_consts = File.new(File.join(path,"constants.h"),"w")
|
318
|
+
file_operations = File.new(File.join(path,"operations.cc"),"w")
|
319
|
+
file_operations_hdr = File.new(File.join(path,"operations.h"),"w")
|
320
|
+
file_conversions = File.new(File.join(path,"conversions.cc"),"w")
|
321
|
+
file_conversions_hdr = File.new(File.join(path,"conversions.hpp"),"w")
|
322
|
+
file_cmakelists = File.new(File.join(path,"CMakeLists.txt"),"w")
|
323
|
+
|
324
|
+
types_hdr = TypesHelperHDR.new("_RBIND_TYPES_H_",@root)
|
325
|
+
file_types_hdr.write @erb_types_hdr.result(types_hdr.binding)
|
326
|
+
|
327
|
+
types = TypesHelper.new("types",@root)
|
328
|
+
file_types.write @erb_types.result(types.binding)
|
329
|
+
|
330
|
+
consts = ConstsHelper.new("_RBIND_CONSTS_H_",@root)
|
331
|
+
file_consts.write @erb_consts.result(consts.binding)
|
332
|
+
|
333
|
+
conversions_hdr = ConversionsHelperHDR.new("_RBIND_CONVERSIONS_H_",@root)
|
334
|
+
conversions_hdr.includes += includes
|
335
|
+
file_conversions_hdr.write @erb_conversions_hdr.result(conversions_hdr.binding)
|
336
|
+
|
337
|
+
conversions = ConversionsHelper.new("conversions",@root)
|
338
|
+
file_conversions.write @erb_conversions.result(conversions.binding)
|
339
|
+
|
340
|
+
operations_hdr = OperationsHDRHelper.new("_RBIND_OPERATIONS_H_",@root)
|
341
|
+
file_operations_hdr.write @erb_operations_hdr.result(operations_hdr.binding)
|
342
|
+
|
343
|
+
operations = OperationsHelper.new("operations",@root)
|
344
|
+
file_operations.write @erb_operations.result(operations.binding)
|
345
|
+
|
346
|
+
if generate_cmake
|
347
|
+
cmakelists = CMakeListsHelper.new(@library_name,@pkg_config)
|
348
|
+
file_cmakelists.write @erb_cmakelists.result(cmakelists.binding)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|