gecoder 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/COPYING +17 -0
  2. data/LGPL-LICENSE +458 -0
  3. data/README +20 -0
  4. data/Rakefile +6 -0
  5. data/ext/extconf.rb +29 -0
  6. data/ext/missing.cpp +295 -0
  7. data/ext/missing.h +116 -0
  8. data/ext/vararray.cpp +312 -0
  9. data/ext/vararray.h +146 -0
  10. data/lib/gecoder.rb +4 -0
  11. data/lib/gecoder/bindings.rb +7 -0
  12. data/lib/gecoder/bindings/bindings.rb +2055 -0
  13. data/lib/gecoder/interface.rb +6 -0
  14. data/lib/gecoder/interface/binding_changes.rb +111 -0
  15. data/lib/gecoder/interface/branch.rb +102 -0
  16. data/lib/gecoder/interface/constraints.rb +10 -0
  17. data/lib/gecoder/interface/constraints/distinct.rb +15 -0
  18. data/lib/gecoder/interface/constraints/linear.rb +158 -0
  19. data/lib/gecoder/interface/constraints/relation.rb +76 -0
  20. data/lib/gecoder/interface/enum_wrapper.rb +64 -0
  21. data/lib/gecoder/interface/model.rb +130 -0
  22. data/lib/gecoder/interface/search.rb +23 -0
  23. data/vendor/rust/README +28 -0
  24. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  25. data/vendor/rust/include/rust_checks.hh +115 -0
  26. data/vendor/rust/include/rust_conversions.hh +103 -0
  27. data/vendor/rust/rust.rb +67 -0
  28. data/vendor/rust/rust/attribute.rb +51 -0
  29. data/vendor/rust/rust/bindings.rb +172 -0
  30. data/vendor/rust/rust/class.rb +334 -0
  31. data/vendor/rust/rust/constants.rb +48 -0
  32. data/vendor/rust/rust/container.rb +110 -0
  33. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  34. data/vendor/rust/rust/cwrapper.rb +72 -0
  35. data/vendor/rust/rust/cxxclass.rb +98 -0
  36. data/vendor/rust/rust/element.rb +81 -0
  37. data/vendor/rust/rust/enum.rb +63 -0
  38. data/vendor/rust/rust/function.rb +407 -0
  39. data/vendor/rust/rust/namespace.rb +61 -0
  40. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  41. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  42. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  43. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  44. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  45. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  46. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  47. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  48. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
  49. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  50. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +12 -0
  51. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  52. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  53. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  54. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  55. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  56. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  57. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  58. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  59. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +5 -0
  60. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  61. data/vendor/rust/rust/type.rb +98 -0
  62. data/vendor/rust/test/Makefile +4 -0
  63. data/vendor/rust/test/constants.rb +35 -0
  64. data/vendor/rust/test/cppclass.cc +40 -0
  65. data/vendor/rust/test/cppclass.hh +63 -0
  66. data/vendor/rust/test/cppclass.rb +59 -0
  67. data/vendor/rust/test/cwrapper.c +74 -0
  68. data/vendor/rust/test/cwrapper.h +41 -0
  69. data/vendor/rust/test/cwrapper.rb +56 -0
  70. data/vendor/rust/test/dummyclass.hh +31 -0
  71. data/vendor/rust/test/lib/extension-test.rb +98 -0
  72. data/vendor/rust/test/test-constants.rb +43 -0
  73. data/vendor/rust/test/test-cppclass.rb +82 -0
  74. data/vendor/rust/test/test-cwrapper.rb +77 -0
  75. metadata +144 -0
@@ -0,0 +1,81 @@
1
+ # Copyright (c) 2005-2007 Diego Pettenò <flameeyes@gmail.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge,
7
+ # publish, distribute, sublicense, and/or sell copies of the Software,
8
+ # and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
+ # BE LIABLE
19
+ # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ module Rust
24
+
25
+ # This class represents a generic element for Rust, that responds to
26
+ # the three generic methods: Element.declaration, Element.definition
27
+ # and Element.initialization that form a Ruby extension generated by
28
+ # Rust.
29
+ # An element can also have children element, which methods are
30
+ # called as a pyramid.
31
+ class Element
32
+ def initialize
33
+ @children = []
34
+ @expansions = []
35
+
36
+ @declaration_template = "#error Element #{self.inspect} missing declaration template"
37
+ @definition_template = "#error Element #{self.inspect} missing definition template"
38
+ @initializatio_template = "#error Element #{self.inspect} missing initialization template"
39
+ end
40
+
41
+ def add_expansion(key, value = key)
42
+ throw "missing @expansions array -- did you call Element.initialize?" unless @expansions
43
+ @expansions << [key, value]
44
+ end
45
+
46
+ def expand(str)
47
+ @expansions.each do |key, expression|
48
+ begin
49
+ str.gsub!("!#{key}!", eval(expression).to_s)
50
+ rescue
51
+ $stderr.puts "Exception during substitution of '#{key}' into '#{expression}' for #{self.inspect}"
52
+ raise
53
+ end
54
+ end
55
+
56
+ return str
57
+ end
58
+
59
+ def declaration
60
+ ret = @declaration_template +
61
+ @children.collect { |child| child.declaration }.join("\n")
62
+
63
+ expand(ret)
64
+ end
65
+
66
+ def definition
67
+ ret = @definition_template +
68
+ @children.collect { |child| child.definition }.join("\n")
69
+
70
+ expand(ret)
71
+ end
72
+
73
+ def initialization
74
+ ret = @initialization_template +
75
+ @children.collect { |child| child.initialization }.join("\n")
76
+
77
+ expand(ret)
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright (c) 2007 Diego Pettenò <flameeyes@gmail.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge,
7
+ # publish, distribute, sublicense, and/or sell copies of the Software,
8
+ # and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
+ # BE LIABLE
19
+ # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ module Rust
24
+ # This class represent an enumeration type. The only reason to bind
25
+ # an enumeration in Ruby with something more than than an integer
26
+ # conversion is so that you can actually validate the parameter
27
+ # passed so that an exception is thrown if the value is out of scope.
28
+ class Enum < Element
29
+ def initialize(name, parent, ctype = nil) # :notnew
30
+ super()
31
+
32
+ @name = name
33
+ @parent = parent
34
+
35
+ @cprefix = "#{@parent.cname}::" if @parent
36
+ @cname = "#{@cprefix}#{@name}"
37
+
38
+ @varname = "#{@cname.gsub("::", "_")}"
39
+ @cname = ctype if ctype
40
+
41
+ @values = []
42
+
43
+ @declaration_template = Templates["EnumDeclarations"]
44
+ @definition_template = Templates["EnumDefinitions"]
45
+ @initialization_template = "!enum_values_init!"
46
+
47
+ add_expansion 'enum_values_init',
48
+ '@values.collect { |name, value| "rb_define_const(!parent_varname!, \"#{name}\", cxx2ruby(#{value}));" }.join("\n")'
49
+ add_expansion 'enum_cases',
50
+ '@values.collect { |name, value| "case #{value}:" }.join("\n")'
51
+ add_expansion 'enum_name', '@name'
52
+ add_expansion 'enum_cname', '@cname'
53
+ add_expansion 'enum_cprefix', '@cprefix'
54
+ add_expansion 'enum_varname', '@varname'
55
+ add_expansion 'parent_varname', '"r#{@parent.varname}"'
56
+ end
57
+
58
+ def add_value(name, value="#{@cprefix}#{name}")
59
+ @values << [name, value]
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,407 @@
1
+ # Copyright (c) 2005-2007 Diego Pettenò <flameeyes@gmail.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge,
7
+ # publish, distribute, sublicense, and/or sell copies of the Software,
8
+ # and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
+ # BE LIABLE
19
+ # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'set'
24
+ require 'rust/element'
25
+ require 'rust/type'
26
+
27
+ module Rust
28
+ # This class represent an abstracted bound function; it is not
29
+ # supposed to be used directly, instead its subclass should be used,
30
+ # like CxxClass::Method.
31
+ class Function < Element
32
+ # Class representing a function or method parameter
33
+ class Parameter < Type
34
+
35
+ attr_reader :argname, :optional
36
+ attr_accessor :custom_conversion
37
+ attr_accessor :index
38
+
39
+ def initialize(type, argname, optional) #:notnew:
40
+ super(type)
41
+ @argname = argname
42
+ @optional = optional
43
+ @index = -1
44
+ end
45
+
46
+ # Returns the C/C++ call to convert the (named) parameter from its
47
+ # ruby value to the C/C++ corresponding variable
48
+ def conversion
49
+ return internal_conversion(@argname)
50
+ end
51
+
52
+ # Returns the C/C++ call to convert the (indexed) parameter from
53
+ # its ruby value to the C/C++ corresponding variable, for
54
+ # variable-argument function calls.
55
+ def index_conversion(index)
56
+ raise TypeError, "index not an integer" if index.class != Fixnum
57
+ return internal_conversion("argv[#{index}]")
58
+ end
59
+
60
+ # Internal conversion funciton used by Parameter.conversion
61
+ # and Parameter.index_conversion public functions.
62
+ def internal_conversion(variable)
63
+ return @custom_conversion.to_s if not @custom_conversion.to_s.empty?
64
+ if ruby_type?
65
+ variable
66
+ else
67
+ "ruby2#{valid_name}(#{variable}, #{@index})"
68
+ end
69
+ end
70
+ private :internal_conversion
71
+
72
+ end
73
+
74
+ # This class describes a parameter with a default value: this
75
+ # creates a variable-argument function, where this parameter can
76
+ # be skipped. If missing, the default value will be used.
77
+ class DefaultParameter < Parameter
78
+ attr_reader :default
79
+
80
+ def initialize(type, name, value)
81
+ super(type, name, false)
82
+
83
+ @default = value
84
+ end
85
+ end
86
+
87
+ # This class describe a parameter that is given a static value:
88
+ # such a parameter won't be available on the Ruby side of the
89
+ # interface, instead it will be replaced during call with a
90
+ # static value, that can be a constant value or the name of a
91
+ # variable that is visible in the scope of the function call, like
92
+ # the tmp variable (the instance pointer) or another parameter of
93
+ # the same function, or a function call to transform the value of
94
+ # another parameter of the function.
95
+ class StaticParameter < Parameter
96
+ attr_reader :value
97
+
98
+ def initialize(value)
99
+ @value = value
100
+ end
101
+
102
+ private :conversion, :index_conversion, :argname, :type
103
+ end
104
+
105
+ attr_reader :varname, :name, :parameters, :optional_count
106
+ attr_writer :parameters
107
+
108
+ # Initialisation function, sets the important parameters from the
109
+ # params hash provided, and the derived information that are needed.
110
+ def initialize(params) # :notnew:
111
+ super()
112
+
113
+ @overloads = {}
114
+ @return = params[:return]
115
+ @name = params[:name]
116
+ @bindname = params[:bindname]
117
+ @parent = params[:parent]
118
+ @optional_count = 0
119
+
120
+ @varname = "f#{@parent.varname}#{@name}"
121
+
122
+ @aliases = Set.new
123
+ @variable = false # Variable arguments function
124
+
125
+ @parameters = Array.new
126
+ nocamel_bindname = @bindname.gsub(/([^A-Z])([A-Z])([^A-Z])/) do
127
+ |letter| "#{$1}_#{$2.downcase}#{$3}"
128
+ end
129
+
130
+ @aliases << nocamel_bindname unless nocamel_bindname == @bindname
131
+
132
+ @declaration_template = "!function_prototype!;\n"
133
+ @definition_template = Templates["FunctionDefinition"]
134
+ @prototype_template = "VALUE !function_varname! ( VALUE self !function_parameters! )"
135
+ @initialization_template = Templates["FunctionInitBinding"]
136
+
137
+ add_expansion 'function_aliases', '@aliases.collect { |alii| Templates["FunctionInitAlias"].gsub("!function_alias!", alii) }.join("\n")'
138
+ add_expansion 'function_prototype', '@prototype_template'
139
+ add_expansion 'function_parameters', 'ruby_parameters'
140
+ add_expansion 'function_call', 'stub'
141
+ add_expansion 'function_varname', 'varname'
142
+ add_expansion 'function_cname', '@name'
143
+ add_expansion 'function_paramcount', 'paramcount'
144
+ add_expansion 'function_bindname', '@bindname'
145
+ add_expansion 'parent_varname', '@parent.varname'
146
+ end
147
+
148
+ # Adds an alias for the function.
149
+ # The same C++ function can be bound with more than one name,
150
+ # as CamelCase names in the methods are bound also with
151
+ # ruby_style names, so that the users can choose what to use.
152
+ def add_alias(name)
153
+ @aliases << name
154
+
155
+ nocamel_alias = name.gsub(/([^A-Z])([A-Z])([^A-Z])/) do
156
+ |letter| "#{$1}_#{$2.downcase}#{$3}"
157
+ end
158
+
159
+ @aliases << nocamel_alias unless nocamel_alias == name
160
+ end
161
+
162
+ # Adds a new parameter to the function
163
+ def add_parameter(name, type, optional = false)
164
+ param = Parameter.new(name, type, optional)
165
+ param.index = @parameters.size+1
166
+
167
+ if optional
168
+ @variable = true
169
+ @prototype_template = "VALUE !function_varname! ( int argc, VALUE *argv, VALUE self )"
170
+ @optional_count += 1
171
+ end
172
+
173
+ yield param if block_given?
174
+
175
+ @parameters << param
176
+
177
+ return param
178
+ end
179
+
180
+ # Adds a parameter with a default value.
181
+ # See Rust::Function::DefaultParameter
182
+ def add_parameter_default(name, type, value)
183
+ @variable = true
184
+ @prototype_template = "VALUE !function_varname! ( int argc, VALUE *argv, VALUE self )"
185
+
186
+ param = DefaultParameter.new(name, type, value)
187
+
188
+ @parameters << param
189
+
190
+ return param
191
+ end
192
+
193
+ # Adds a constant parameter, see Rust::Function::StaticParameter
194
+ def add_static_parameter(value)
195
+ param = StaticParameter.new(value)
196
+
197
+ @parameters << param
198
+
199
+ return param
200
+ end
201
+
202
+ # Set different, non-default templates for functions, that can be used
203
+ # when many functions of the bound C/C++ library contains functions
204
+ # that require to be handled in a particular way.
205
+ def set_custom(prototype, definition, argc)
206
+ @definition_template = definition
207
+ @prototype_template = prototype
208
+ @custom_paramcount = argc
209
+
210
+ @variable = true if argc == -1
211
+ end
212
+
213
+ # Gets the parameters' count. For variable-arguments functions,
214
+ # this returns -1, while for other functions the count depends on
215
+ # the parameters added, as there might be parameters which are
216
+ # passed constant values (e.g. the instance parameter for class
217
+ # wrappers), that are not counted for Ruby-side parameters count.
218
+ def paramcount
219
+ return @custom_paramcount if not @custom_paramcount.nil?
220
+ return -1 if @variable
221
+
222
+ paramcount = 0
223
+ @parameters.each do |param|
224
+ paramcount = paramcount +1 unless param.respond_to?("value")
225
+ end
226
+
227
+ return paramcount
228
+ end
229
+
230
+ # Provides a string with the parameters that are actually
231
+ def ruby_parameters
232
+ @parameters.collect do |param|
233
+ next if param.respond_to?("value")
234
+
235
+ ", VALUE #{param.argname}"
236
+ end.join
237
+ end
238
+
239
+ # Returns an array of the valid cases for variable-argument calls.
240
+ # For instance, a function might need _at least_ three parameters,
241
+ # and can accept _up to_ nine parameters. In that case the range
242
+ # would be 3..9.
243
+ # The upper boundary is always the same of paramcount, while the
244
+ # lower depends on the first optional parameter found. Parameters
245
+ # with default are like optional parameters.
246
+ def arguments_range
247
+ lower_bound = 0
248
+ @parameters.each do |param|
249
+ break if (param.respond_to?("default") or param.optional)
250
+
251
+ lower_bound = lower_bound +1
252
+ end
253
+
254
+ return lower_bound..paramcount
255
+ end
256
+
257
+ def params_conversion(nparams = nil)
258
+ return if @parameters.empty?
259
+
260
+ variable_arguments = nparams != nil
261
+ nparams = paramcount unless nparams
262
+
263
+ ret = ""
264
+ index = 0
265
+ @parameters.each do |param|
266
+ # If we're done with the parameters requested, then we're in
267
+ # the extra loops, which means we break out unless the current
268
+ # parameter is a default parameter or a constant parameter.
269
+ break unless index < nparams or
270
+ param.respond_to?("default") or
271
+ param.respond_to?("value")
272
+
273
+ case
274
+ when param.respond_to?("value")
275
+ ret << param.value
276
+ when (index < nparams and not variable_arguments)
277
+ ret << param.conversion
278
+ index = index +1 # Only increment for ruby parameters consumed
279
+ when (index < nparams and variable_arguments)
280
+ ret << param.index_conversion(index)
281
+ index = index +1 # Only increment for ruby parameters consumed
282
+ when param.respond_to?("default")
283
+ ret << param.default
284
+ end
285
+
286
+ ret << ","
287
+ end
288
+
289
+ return ret.chomp!(",")
290
+ end
291
+ private :params_conversion
292
+
293
+ def raw_call(nparam = nil)
294
+ if @parent.kind_of?(Namespace)
295
+ scope = "#{@parent.cname}::"
296
+ end
297
+
298
+ "#{scope}#{@name}(#{params_conversion(nparam)})"
299
+ end
300
+ private :raw_call
301
+
302
+ def bind_call(nparam = nil)
303
+ case @return
304
+ when nil
305
+ raise "nil return value is not supported for non-constructors."
306
+ when "void"
307
+ return "#{raw_call(nparam)}; return Qnil;\n"
308
+ else
309
+ type = Type.new(@return)
310
+ if not @return.include?("*") and not type.native?
311
+ "return cxx2ruby( new #{@return.gsub("&", "")}(#{raw_call(nparam)}), true );\n"
312
+ else
313
+ "return cxx2ruby( static_cast<#{@return}>(#{raw_call(nparam)}) );\n"
314
+ end
315
+ end
316
+ end
317
+ # private :bind_call
318
+
319
+
320
+ def add_overload(function)
321
+ argc = function.parameters.size
322
+ if not @overloads.has_key?(argc)
323
+ @overloads[argc] = []
324
+ @variable = true
325
+
326
+ @prototype_template = "VALUE !function_varname! ( int argc, VALUE *argv, VALUE self )"
327
+
328
+ end
329
+
330
+ @overloads[argc] << function
331
+ end
332
+
333
+ def stub
334
+ return bind_call unless @variable
335
+ calls = ""
336
+
337
+
338
+ overloads = @overloads.dup
339
+
340
+ key = @parameters.size
341
+ if not overloads.has_key?(key)
342
+ overloads[key] = [ self ]
343
+ else
344
+ overloads[key] << self
345
+ end
346
+
347
+ options = []
348
+ overloads.each { |argc, functions|
349
+ functions.uniq!
350
+ functions.each { |function|
351
+ if function.optional_count > 0
352
+ option = function.dup
353
+
354
+ option.optional_count.times { |i|
355
+ option.parameters = []
356
+ 0.upto(function.parameters.size() - i - 1) { |pindex|
357
+ option.parameters << function.parameters[pindex].dup
358
+ }
359
+
360
+ options << option
361
+ }
362
+ end
363
+ }
364
+ }
365
+
366
+ options.each { |opt|
367
+ overloads.has_key?(opt.parameters.size) ? overloads[opt.parameters.size] << opt : overloads[opt.parameters.size] = [ opt ]
368
+ }
369
+
370
+ overloads.each { |argc, functions|
371
+ call = " case #{argc}: {\n"
372
+ current_function_index = 0
373
+
374
+ functions.each { |func|
375
+ functions.uniq!
376
+ call += "// Case #{current_function_index}\n"
377
+ argc.times { |argindex| # Verify types
378
+ param = func.parameters[argindex]
379
+ valid_name = param.to_s
380
+
381
+ if not param.native?
382
+ valid_name.gsub!("Ptr", "")
383
+ end
384
+
385
+ if param.array?
386
+ call += " if( is_array(argv[#{argindex}]) ) {\n"
387
+ else
388
+ call += " if( is_#{valid_name}(argv[#{argindex}]) ) {\n"
389
+ end
390
+ }
391
+
392
+ call += " #{func.bind_call(argc)}"
393
+ call += " ok = true;\n"
394
+ call += "}"*argc # closes if's
395
+ call += "\n"
396
+
397
+ current_function_index += 1
398
+ }
399
+ call += " } break;\n"
400
+
401
+ calls << call
402
+ }
403
+
404
+ return Templates["VariableFunctionCall"].gsub("!calls!", calls)
405
+ end
406
+ end
407
+ end