wrapture 0.1.0
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.
- checksums.yaml +7 -0
- data/bin/wrapture +12 -0
- data/lib/wrapture.rb +8 -0
- data/lib/wrapture/class_spec.rb +128 -0
- data/lib/wrapture/validator.rb +16 -0
- data/lib/wrapture/version.rb +5 -0
- data/lib/wrapture/wrapper.rb +266 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 67db9aad9a4383dca21f730d07b2af31642334204a66377167154a4849975005
|
4
|
+
data.tar.gz: de35dd304d427fe35f768567e58684a9217714ec01447c73a5961db1760b6ed1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7afe9e387587d8efa3524566e9d9d4d2d9a87bc82fdcdb4995757c6d86a04eca17c452fee716c63681b84be536398beee5a4b429ec9f8fb34723e6650d72d219
|
7
|
+
data.tar.gz: 62d4696980ec04a870f32cdfc987340f840ba269601996b824db8f4e11f564fe5836943ee1e66cebb1c4e9776b052f7adb5b2eef0f7f92514b9622f1e900200b
|
data/bin/wrapture
ADDED
data/lib/wrapture.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
module Wrapture
|
2
|
+
class ClassSpec
|
3
|
+
def initialize(spec)
|
4
|
+
@spec = ClassSpec.normalize_spec_hash(spec)
|
5
|
+
end
|
6
|
+
|
7
|
+
def generate_wrappers
|
8
|
+
generate_declaration_file
|
9
|
+
generate_definition_file
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.normalize_spec_hash(spec)
|
13
|
+
normalized_spec = spec.dup
|
14
|
+
|
15
|
+
if normalized_spec['constructors'].nil?
|
16
|
+
normalized_spec['constructors'] = []
|
17
|
+
end
|
18
|
+
|
19
|
+
if normalized_spec['equivalent-struct']['members'].nil?
|
20
|
+
normalized_spec['equivalent-struct']['members'] = []
|
21
|
+
end
|
22
|
+
|
23
|
+
if normalized_spec['functions'].nil?
|
24
|
+
normalized_spec['functions'] = []
|
25
|
+
else
|
26
|
+
normalized_spec['functions'].each do |function_spec|
|
27
|
+
if function_spec['params'].nil?
|
28
|
+
function_spec['params'] = []
|
29
|
+
end
|
30
|
+
|
31
|
+
if function_spec['wrapped-function']['params'].nil?
|
32
|
+
function_spec['wrapped-function']['params'] = []
|
33
|
+
end
|
34
|
+
|
35
|
+
if function_spec['return'].nil?
|
36
|
+
function_spec['return'] = {}
|
37
|
+
function_spec['return']['type'] = 'void'
|
38
|
+
end
|
39
|
+
|
40
|
+
if function_spec['return']['includes'].nil?
|
41
|
+
function_spec['return']['includes'] = []
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if normalized_spec['constants'].nil?
|
47
|
+
normalized_spec['constants'] = []
|
48
|
+
|
49
|
+
else
|
50
|
+
normalized_spec['constants'].each do |constant_spec|
|
51
|
+
if constant_spec['includes'].nil?
|
52
|
+
constant_spec['includes'] = []
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
return normalized_spec
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def header_guard
|
63
|
+
"__#{@spec['name'].upcase}_HPP"
|
64
|
+
end
|
65
|
+
|
66
|
+
def declaration_includes
|
67
|
+
includes = []
|
68
|
+
|
69
|
+
includes.concat @spec['equivalent-struct']['includes']
|
70
|
+
|
71
|
+
@spec['functions'].each do |function_spec|
|
72
|
+
includes.concat function_spec['return']['includes']
|
73
|
+
end
|
74
|
+
|
75
|
+
includes.uniq
|
76
|
+
end
|
77
|
+
|
78
|
+
def pointer_wrapper?
|
79
|
+
@spec['constructors'].each do |constructor_spec|
|
80
|
+
if constructor_spec['wrapped-function']['return']['type'] == 'equivalent-struct-pointer'
|
81
|
+
return true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
|
88
|
+
def equivalent_name
|
89
|
+
if pointer_wrapper?
|
90
|
+
'*equivalent'
|
91
|
+
else
|
92
|
+
'equivalent'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def generate_declaration_file
|
97
|
+
file = File.open("#{@spec['name']}.hpp", 'w')
|
98
|
+
|
99
|
+
file.puts "#ifndef #{header_guard}"
|
100
|
+
file.puts "#define #{header_guard}"
|
101
|
+
|
102
|
+
file.puts unless declaration_includes.empty?
|
103
|
+
declaration_includes.each do |include_file|
|
104
|
+
file.puts "#include <#{include_file}"
|
105
|
+
end
|
106
|
+
|
107
|
+
file.puts "namespace #{@spec['namespace']} {"
|
108
|
+
file.puts " class #{@spec['name']} {"
|
109
|
+
file.puts ' public:'
|
110
|
+
|
111
|
+
file.puts unless @spec['constants'].empty?
|
112
|
+
@spec['constants'].each do |constant_spec|
|
113
|
+
file.puts " static const #{constant_spec['type']} #{constant_spec['name']}"
|
114
|
+
end
|
115
|
+
|
116
|
+
file.puts
|
117
|
+
file.puts " struct #{@spec['equivalent-struct']['name']} #{equivalent_name}"
|
118
|
+
|
119
|
+
file.puts ' };' # end of class
|
120
|
+
file.puts '}' # end of namespace
|
121
|
+
|
122
|
+
file.close
|
123
|
+
end
|
124
|
+
|
125
|
+
def generate_definition_file
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Wrapture
|
2
|
+
|
3
|
+
def self.normalize_spec(spec)
|
4
|
+
|
5
|
+
normalized_spec = Hash.new
|
6
|
+
normalized_spec['classes'] = Array.new
|
7
|
+
|
8
|
+
spec['classes'].each do |class_spec|
|
9
|
+
normalized_spec['classes'] << ClassSpec.normalize_spec_hash(class_spec)
|
10
|
+
end
|
11
|
+
|
12
|
+
return normalized_spec
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,266 @@
|
|
1
|
+
module Wrapture
|
2
|
+
|
3
|
+
def self.wrap_class( class_spec )
|
4
|
+
|
5
|
+
spec = ClassSpec.new class_spec
|
6
|
+
spec.generate_wrappers
|
7
|
+
|
8
|
+
class_name = class_spec['name']
|
9
|
+
struct_name = class_spec['equivalent-struct']['name']
|
10
|
+
|
11
|
+
# generating constructor signatures
|
12
|
+
constructor_signatures = Array.new
|
13
|
+
equivalent_name = 'equivalent'
|
14
|
+
equivalent_struct = 'this->equivalent'
|
15
|
+
equivalent_struct_pointer = '&this->equivalent'
|
16
|
+
member_operator = '.'
|
17
|
+
|
18
|
+
class_spec['constructors'].each do |constructor_spec|
|
19
|
+
if constructor_spec['wrapped-function']['return']['type'] == 'equivalent-struct-pointer'
|
20
|
+
equivalent_name = '*equivalent'
|
21
|
+
equivalent_struct = '*(this->equivalent)'
|
22
|
+
equivalent_struct_pointer = 'this->equivalent'
|
23
|
+
member_operator = '->'
|
24
|
+
end
|
25
|
+
|
26
|
+
params = Array.new
|
27
|
+
constructor_spec['wrapped-function']['params'].each do |param|
|
28
|
+
params << "#{param['type']} #{param['name']}"
|
29
|
+
end
|
30
|
+
|
31
|
+
constructor_signatures << "#{class_name}( #{params.join ', '} )"
|
32
|
+
end
|
33
|
+
|
34
|
+
members = Array.new
|
35
|
+
class_spec['equivalent-struct']['members'].each do |member|
|
36
|
+
members << "#{member['type']} #{member['name']}"
|
37
|
+
end
|
38
|
+
|
39
|
+
member_constructor_signature = "#{class_name}( #{members.join ', '} )"
|
40
|
+
struct_constructor_signature = "#{class_name}( struct #{struct_name} equivalent )"
|
41
|
+
pointer_constructor_signature = "#{class_name}( const struct #{struct_name} *equivalent )"
|
42
|
+
|
43
|
+
# get the list of includes for declarations
|
44
|
+
declaration_includes = class_spec['equivalent-struct']['includes'].dup
|
45
|
+
class_spec['functions'].each do |function_spec|
|
46
|
+
declaration_includes.concat function_spec['return']['includes']
|
47
|
+
end
|
48
|
+
declaration_includes.uniq!
|
49
|
+
|
50
|
+
# generate the header file
|
51
|
+
File.open("#{class_name}.hpp", 'w') do |file|
|
52
|
+
# header guard
|
53
|
+
file.puts "#ifndef __#{class_name.upcase}_HPP"
|
54
|
+
file.puts "#define __#{class_name.upcase}_HPP"
|
55
|
+
|
56
|
+
file.puts
|
57
|
+
|
58
|
+
declaration_includes.each do |include_file|
|
59
|
+
file.puts "#include <#{include_file}>"
|
60
|
+
end
|
61
|
+
|
62
|
+
file.puts unless declaration_includes.empty?
|
63
|
+
|
64
|
+
file.puts "namespace #{class_spec['namespace']} {"
|
65
|
+
file.puts " class #{class_name} {"
|
66
|
+
file.puts ' public:'
|
67
|
+
|
68
|
+
class_spec['constants'].each do |constant_spec|
|
69
|
+
file.puts " static const #{constant_spec['type']} #{constant_spec['name']};"
|
70
|
+
end
|
71
|
+
file.puts unless class_spec['constants'].empty?
|
72
|
+
|
73
|
+
file.puts " struct #{struct_name} #{equivalent_name};"
|
74
|
+
file.puts
|
75
|
+
|
76
|
+
constructor_signatures.each do |signature|
|
77
|
+
file.puts " #{signature};"
|
78
|
+
end
|
79
|
+
|
80
|
+
unless members.empty?
|
81
|
+
file.puts " #{member_constructor_signature};"
|
82
|
+
end
|
83
|
+
|
84
|
+
file.puts " #{struct_constructor_signature};"
|
85
|
+
file.puts " #{pointer_constructor_signature};"
|
86
|
+
|
87
|
+
class_spec['equivalent-struct']['members'].each do |member|
|
88
|
+
file.puts " #{member['type']} Get#{member['name'].capitalize}( void ) const;"
|
89
|
+
file.puts " void Set#{member['name'].capitalize}( #{member['type']} #{member['name']} );"
|
90
|
+
end
|
91
|
+
|
92
|
+
class_spec['functions'].each do |function_spec|
|
93
|
+
static_modifier = if function_spec['static'] then 'static ' else '' end
|
94
|
+
file.write " #{static_modifier}#{function_spec['return']['type']} #{function_spec['name']}( "
|
95
|
+
|
96
|
+
wrapped_params = Array.new
|
97
|
+
function_spec['params'].each do |param|
|
98
|
+
wrapped_params << "#{param['type']} #{param['name']}"
|
99
|
+
end
|
100
|
+
file.write(wrapped_params.join ', ')
|
101
|
+
|
102
|
+
file.puts ' );'
|
103
|
+
end
|
104
|
+
|
105
|
+
# destructor
|
106
|
+
unless class_spec['destructor'].nil?
|
107
|
+
file.puts " ~#{class_name}( void );"
|
108
|
+
end
|
109
|
+
|
110
|
+
file.puts ' };' # end of class
|
111
|
+
file.puts '}' # end of namespace
|
112
|
+
file.puts '#endif' # end of header guard
|
113
|
+
end
|
114
|
+
|
115
|
+
# get the complete list of includes for definitions
|
116
|
+
definition_includes = Array.new
|
117
|
+
definition_includes << "#{class_name}.hpp"
|
118
|
+
class_spec['functions'].each do |function_spec|
|
119
|
+
definition_includes.concat function_spec['return']['includes']
|
120
|
+
definition_includes.concat function_spec['wrapped-function']['includes']
|
121
|
+
end
|
122
|
+
|
123
|
+
class_spec['constants'].each do |constant_spec|
|
124
|
+
definition_includes.concat constant_spec['includes']
|
125
|
+
end
|
126
|
+
definition_includes.uniq!
|
127
|
+
|
128
|
+
# generate the definition file
|
129
|
+
File.open("#{class_name}.cpp", 'w') do |file|
|
130
|
+
definition_includes.each do |include_file|
|
131
|
+
file.puts "#include <#{include_file}>"
|
132
|
+
end
|
133
|
+
|
134
|
+
file.puts
|
135
|
+
file.puts "namespace #{class_spec['namespace']} {"
|
136
|
+
|
137
|
+
# constants
|
138
|
+
class_spec['constants'].each do |constant_spec|
|
139
|
+
file.puts
|
140
|
+
file.puts " const #{constant_spec['type']} #{class_name}::#{constant_spec['name']} = #{constant_spec['value']};"
|
141
|
+
end
|
142
|
+
|
143
|
+
# constructors
|
144
|
+
class_spec['constructors'].each_index do |i|
|
145
|
+
wrapped_function = class_spec['constructors'][i]['wrapped-function']
|
146
|
+
function_params = Array.new
|
147
|
+
wrapped_function['params'].each do |param|
|
148
|
+
function_params << param['name']
|
149
|
+
end
|
150
|
+
|
151
|
+
file.puts
|
152
|
+
file.puts " #{class_name}::#{constructor_signatures[i]} {"
|
153
|
+
file.write(' ')
|
154
|
+
case wrapped_function['return']['type']
|
155
|
+
when 'equivalent-struct'
|
156
|
+
file.write(equivalent_struct)
|
157
|
+
when 'equivalent-struct-pointer'
|
158
|
+
file.write(equivalent_struct_pointer)
|
159
|
+
end
|
160
|
+
file.puts " = #{wrapped_function['name']}( #{function_params.join ', '} );"
|
161
|
+
file.puts ' }'
|
162
|
+
end
|
163
|
+
|
164
|
+
unless members.empty?
|
165
|
+
file.puts
|
166
|
+
file.puts " #{class_name}::#{member_constructor_signature} {"
|
167
|
+
class_spec['equivalent-struct']['members'].each do |member|
|
168
|
+
file.puts " this->equivalent#{member_operator}#{member['name']} = #{member['name']};"
|
169
|
+
end
|
170
|
+
file.puts ' }' # end of the member constructor
|
171
|
+
end
|
172
|
+
|
173
|
+
file.puts
|
174
|
+
file.puts " #{class_name}::#{struct_constructor_signature} {"
|
175
|
+
class_spec['equivalent-struct']['members'].each do |member|
|
176
|
+
file.puts " this->equivalent#{member_operator}#{member['name']} = equivalent.#{member['name']};"
|
177
|
+
end
|
178
|
+
file.puts ' }' # end of struct conversion
|
179
|
+
|
180
|
+
file.puts
|
181
|
+
file.puts " #{class_name}::#{pointer_constructor_signature} {"
|
182
|
+
class_spec['equivalent-struct']['members'].each do |member|
|
183
|
+
file.puts " this->equivalent#{member_operator}#{member['name']} = equivalent->#{member['name']};"
|
184
|
+
end
|
185
|
+
file.puts ' }' # end of pointer conversion
|
186
|
+
|
187
|
+
class_spec['equivalent-struct']['members'].each do |member|
|
188
|
+
file.puts # line to separate from previous functions
|
189
|
+
file.puts " #{member['type']} #{class_name}::Get#{member['name'].capitalize}( void ) const {"
|
190
|
+
file.puts " return this->equivalent#{member_operator}#{member['name']};"
|
191
|
+
file.puts ' }'
|
192
|
+
file.puts
|
193
|
+
file.puts " void #{class_name}::Set#{member['name'].capitalize}( #{member['type']} #{member['name']} ) {"
|
194
|
+
file.puts " this->equivalent#{member_operator}#{member['name']} = #{member['name']};"
|
195
|
+
file.puts ' }'
|
196
|
+
end
|
197
|
+
|
198
|
+
class_spec['functions'].each do |function_spec|
|
199
|
+
file.puts
|
200
|
+
file.write " #{function_spec['return']['type']} #{class_name}::#{function_spec['name']}( "
|
201
|
+
|
202
|
+
wrapped_params = Array.new
|
203
|
+
function_spec['params'].each do |param|
|
204
|
+
wrapped_params << "#{param['type']} #{param['name']}"
|
205
|
+
end
|
206
|
+
file.write(wrapped_params.join ', ')
|
207
|
+
|
208
|
+
file.puts ' ) {'
|
209
|
+
|
210
|
+
# the function body
|
211
|
+
if function_spec['return']['type'] == 'void'
|
212
|
+
file.write " #{function_spec['wrapped-function']['name']}( "
|
213
|
+
else
|
214
|
+
file.write " return #{function_spec['return']['type']}( #{function_spec['wrapped-function']['name']}( "
|
215
|
+
end
|
216
|
+
|
217
|
+
# building the parameters
|
218
|
+
wrapped_params = Array.new
|
219
|
+
function_spec['wrapped-function']['params'].each do |param|
|
220
|
+
case param['name']
|
221
|
+
when 'equivalent-struct'
|
222
|
+
wrapped_params << equivalent_struct
|
223
|
+
when 'equivalent-struct-pointer'
|
224
|
+
wrapped_params << equivalent_struct_pointer
|
225
|
+
else
|
226
|
+
wrapped_params << param['name']
|
227
|
+
end
|
228
|
+
end
|
229
|
+
file.write(wrapped_params.join ', ')
|
230
|
+
|
231
|
+
if function_spec['return']['type'] == 'void'
|
232
|
+
file.puts ' );'
|
233
|
+
else
|
234
|
+
file.puts ' ) );'
|
235
|
+
end
|
236
|
+
file.puts ' }'
|
237
|
+
end
|
238
|
+
|
239
|
+
# destructor
|
240
|
+
unless class_spec['destructor'].nil?
|
241
|
+
file.puts
|
242
|
+
file.puts " #{class_name}::~#{class_name}( void ) {"
|
243
|
+
file.write(" #{class_spec['destructor']['wrapped-function']['name']}( ")
|
244
|
+
wrapped_params = Array.new
|
245
|
+
class_spec['destructor']['wrapped-function']['params'].each do |param|
|
246
|
+
case param['name']
|
247
|
+
when 'equivalent-struct'
|
248
|
+
wrapped_params << equivalent_struct
|
249
|
+
when 'equivalent-struct-pointer'
|
250
|
+
wrapped_params << equivalent_struct_pointer
|
251
|
+
else
|
252
|
+
wrapped_params << param['name']
|
253
|
+
end
|
254
|
+
end
|
255
|
+
file.write(wrapped_params.join ', ')
|
256
|
+
file.puts ' );'
|
257
|
+
file.puts ' }'
|
258
|
+
end
|
259
|
+
|
260
|
+
file.puts # line after last function
|
261
|
+
file.puts '}' # end of namespace
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wrapture
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joel Anderson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Wraps C code in C++.
|
14
|
+
email: joelanderson333@gmail.com
|
15
|
+
executables:
|
16
|
+
- wrapture
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/wrapture
|
21
|
+
- lib/wrapture.rb
|
22
|
+
- lib/wrapture/class_spec.rb
|
23
|
+
- lib/wrapture/validator.rb
|
24
|
+
- lib/wrapture/version.rb
|
25
|
+
- lib/wrapture/wrapper.rb
|
26
|
+
homepage: http://rubygems.org/gems/wrapture
|
27
|
+
licenses:
|
28
|
+
- Apache-2.0
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubygems_version: 3.0.1
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: wrap C in C++
|
49
|
+
test_files: []
|