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 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
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yaml'
4
+ require 'wrapture'
5
+
6
+ spec = YAML.load_file ARGV[0]
7
+
8
+ normalized_spec = Wrapture.normalize_spec spec
9
+
10
+ normalized_spec['classes'].each do |class_spec|
11
+ Wrapture.wrap_class class_spec
12
+ end
data/lib/wrapture.rb ADDED
@@ -0,0 +1,8 @@
1
+ module Wrapture
2
+
3
+ require 'wrapture/class_spec'
4
+ require 'wrapture/wrapper'
5
+ require 'wrapture/validator'
6
+ require 'wrapture/version'
7
+
8
+ end
@@ -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,5 @@
1
+ module Wrapture
2
+
3
+ VERSION = '0.1.0'
4
+
5
+ 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: []