Class: Rbind::Rbind
- Inherits:
-
Object
show all
- Defined in:
- lib/rbind/rbind.rb
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(name, parser = DefaultParser.new) ⇒ Rbind
Returns a new instance of Rbind.
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/rbind/rbind.rb', line 28
def initialize(name,parser = DefaultParser.new)
@name = GeneratorRuby.name
@includes = []
@pkg_config = []
@rbind_pkgs= []
@parser = parser
lib_name = "rbind_#{name.downcase}"
@generator_c = GeneratorC.new(@parser,name,lib_name)
@generator_ruby = GeneratorRuby.new(@parser,name,lib_name)
@generator_extern = GeneratorExtern.new(@parser)
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args) ⇒ Object
205
206
207
208
209
210
211
212
213
|
# File 'lib/rbind/rbind.rb', line 205
def method_missing(m,*args)
t = @parser.type(m.to_s,false,false)
return t if t
op = @parser.operation(m.to_s,false)
return op if op
super
end
|
Instance Attribute Details
#generator_c ⇒ Object
Returns the value of attribute generator_c.
6
7
8
|
# File 'lib/rbind/rbind.rb', line 6
def generator_c
@generator_c
end
|
#generator_ruby ⇒ Object
Returns the value of attribute generator_ruby.
7
8
9
|
# File 'lib/rbind/rbind.rb', line 7
def generator_ruby
@generator_ruby
end
|
#includes ⇒ Object
Returns the value of attribute includes.
8
9
10
|
# File 'lib/rbind/rbind.rb', line 8
def includes
@includes
end
|
#name ⇒ Object
Returns the value of attribute name.
9
10
11
|
# File 'lib/rbind/rbind.rb', line 9
def name
@name
end
|
#parser ⇒ Object
Returns the value of attribute parser.
5
6
7
|
# File 'lib/rbind/rbind.rb', line 5
def parser
@parser
end
|
#pkg_config ⇒ Object
Returns the value of attribute pkg_config.
10
11
12
|
# File 'lib/rbind/rbind.rb', line 10
def pkg_config
@pkg_config
end
|
#rbind_pkgs ⇒ Object
11
12
13
|
# File 'lib/rbind/rbind.rb', line 11
def rbind_pkgs
@rbind_pkgs
end
|
Class Method Details
.pkg_paths(pkg_name) ⇒ Object
13
14
15
16
17
18
19
20
|
# File 'lib/rbind/rbind.rb', line 13
def self.pkg_paths(pkg_name)
out = IO.popen("pkg-config --cflags-only-I #{pkg_name}")
paths = out.read.split("-I").delete_if(&:empty?).map do |i|
i.gsub("\n","").gsub(" ","")
end
raise "Cannot find pkg paths for #{pkg_name}" if paths.empty?
paths
end
|
.rbind_pkg_path(name) ⇒ Object
22
23
24
25
26
|
# File 'lib/rbind/rbind.rb', line 22
def self.rbind_pkg_path(name)
files = Gem.find_files("#{name}/rbind/extern.rbind")
raise "Cannot find paths for rbind package #{name}" if files.empty?
File.dirname(files.first)
end
|
Instance Method Details
#add_std_except ⇒ Object
188
189
190
191
192
193
194
195
196
|
# File 'lib/rbind/rbind.rb', line 188
def add_std_except
@generator_c.includes << "<stdexcept>"
exception = RClass.new(RBase.normalize("std::exception"))
@parser.add_type(exception)
runtime_error = RClass.new(RBase.normalize("std::runtime_error"))
runtime_error.add_parent(exception)
@parser.add_type(runtime_error)
end
|
#add_std_map ⇒ Object
183
184
185
186
|
# File 'lib/rbind/rbind.rb', line 183
def add_std_map
@generator_c.includes << "<map>"
@parser.add_type(StdMap.new("std::map"))
end
|
#add_std_string(with_c_string = true) ⇒ Object
169
170
171
172
173
174
175
|
# File 'lib/rbind/rbind.rb', line 169
def add_std_string(with_c_string = true)
@generator_c.includes << "<string>"
@generator_c.includes << "<cstring>" if with_c_string
@parser.add_type(StdString.new("std::string",@parser))
@parser.type_alias["basic_string"] = @parser.std.string
self
end
|
#add_std_types ⇒ Object
198
199
200
201
202
203
|
# File 'lib/rbind/rbind.rb', line 198
def add_std_types
add_std_vector
add_std_string
add_std_map
add_std_except
end
|
#add_std_vector ⇒ Object
177
178
179
180
181
|
# File 'lib/rbind/rbind.rb', line 177
def add_std_vector
@generator_c.includes << "<vector>"
@parser.add_type(StdVector.new("std::vector"))
self
end
|
#build ⇒ Object
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/rbind/rbind.rb', line 106
def build
::Rbind.log.info "build c wrappers"
path = File.join(generator_c.output_path,"build")
FileUtils.mkdir_p(path) if path && !File.directory?(path)
Dir.chdir(path) do
if !system("cmake -C ..")
raise "CMake Configure Error"
end
if !system("make")
raise "Make Build Error"
end
end
if !system("cp #{File.join(path,"lib*.*")} #{generator_ruby.output_path}")
raise "cannot copy library to #{generator_ruby.output_path}"
end
::Rbind.log.info "all done !"
end
|
#check_python ⇒ Object
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/rbind/rbind.rb', line 48
def check_python
out = IO.popen("which python")
if(out.read.empty?)
raise 'Cannot find python interpreter needed for parsing header files'
end
in_,out,err = Open3.popen3("python --version")
str = err.read
str = if str.empty?
out.read
else
str
end
if(str =~ /[a-zA-Z]* (.*)/)
if $1.to_f < 2.7
raise "Wrong python version #{$1}. At least python 2.7 is needed for parsing header files"
end
else
raise 'Cannot determine python version needed for parsing header files'
end
end
|
#generate(c_path = "src", ruby_path = "ruby/lib/#{name.downcase}") ⇒ Object
124
125
126
127
128
|
# File 'lib/rbind/rbind.rb', line 124
def generate(c_path = "src",ruby_path = "ruby/lib/#{name.downcase}")
generate_c c_path,ruby_path
generate_extern ruby_path,c_path
generate_ruby ruby_path
end
|
#generate_c(path, ruby_path) ⇒ Object
136
137
138
139
140
141
142
|
# File 'lib/rbind/rbind.rb', line 136
def generate_c(path,ruby_path)
::Rbind.log.info "generate c wrappers"
@generator_c.includes += includes
@generator_c.includes.uniq!
@generator_c.pkg_config = pkg_config
@generator_c.generate(path,ruby_path)
end
|
#generate_extern(path, cpath) ⇒ Object
144
145
146
|
# File 'lib/rbind/rbind.rb', line 144
def generate_extern(path,cpath)
@generator_extern.generate(File.join(path,"rbind"),@generator_ruby.module_name,@generator_ruby.file_prefix,cpath)
end
|
#generate_ruby(path) ⇒ Object
130
131
132
133
134
|
# File 'lib/rbind/rbind.rb', line 130
def generate_ruby(path)
::Rbind.log.info "generate ruby ffi wrappers"
@generator_ruby.required_module_names = rbind_pkgs
@generator_ruby.generate(path)
end
|
#libs ⇒ Object
165
166
167
|
# File 'lib/rbind/rbind.rb', line 165
def libs
@generator_c.libs
end
|
#on_type_not_found(&block) ⇒ Object
161
162
163
|
# File 'lib/rbind/rbind.rb', line 161
def on_type_not_found(&block)
@parser.on_type_not_found(&block)
end
|
#parse(*files) ⇒ Object
41
42
43
44
45
46
|
# File 'lib/rbind/rbind.rb', line 41
def parse(*files)
files.flatten.each do |path|
raise ArgumentError, "File '#{path}' does not exist" if not File.exists?(path)
parser.parse File.new(path).read
end
end
|
#parse_extern ⇒ Object
parses other rbind packages
70
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/rbind/rbind.rb', line 70
def parse_extern
local_parser = DefaultParser.new(parser)
@rbind_pkgs.each do |pkg|
path = Rbind.rbind_pkg_path(pkg)
config = YAML.load(File.open(File.join(path,"config.rbind")).read)
path = File.join(path,"extern.rbind")
::Rbind.log.info "parsing extern rbind file #{path}"
local_parser.parse(File.open(path).read,config.ruby_module_name)
end
self
end
|
102
103
104
|
# File 'lib/rbind/rbind.rb', line 102
def ()
parser.parse ()
end
|
98
99
100
|
# File 'lib/rbind/rbind.rb', line 98
def (*)
parser.parse (*)
end
|
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/rbind/rbind.rb', line 83
def (*)
check_python
= if .empty?
includes
else
end
= .map do |h|
"\"#{h}\""
end
path = File.join(File.dirname(__FILE__),'tools','hdr_parser.py')
out = IO.popen("python #{path} #{.join(" ")}")
out.read
end
|
#type(*args) ⇒ Object
157
158
159
|
# File 'lib/rbind/rbind.rb', line 157
def type(*args)
parser.type(*args)
end
|
#use_namespace(name) ⇒ Object
148
149
150
151
152
153
154
155
|
# File 'lib/rbind/rbind.rb', line 148
def use_namespace(name)
t = if name.is_a? String
parser.type(name)
else
name
end
parser.use_namespace t
end
|