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,103 @@
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
+
24
+ #ifndef __RUST_CONVERSIONS__
25
+ #define __RUST_CONVERSIONS__
26
+
27
+ #include <stdint.h>
28
+ #include <ruby.h>
29
+
30
+ /* Standard conversions for integer values */
31
+
32
+ static inline uint32_t ruby2uint(VALUE rval, int argn = -1) {
33
+ return NUM2UINT(rval);
34
+ }
35
+
36
+ static inline int32_t ruby2int(VALUE rval, int argn = -1) {
37
+ return NUM2INT(rval);
38
+ }
39
+
40
+ static inline VALUE cxx2ruby(int32_t val) {
41
+ return INT2FIX(val);
42
+ }
43
+
44
+ static inline VALUE cxx2ruby(uint32_t val) {
45
+ return INT2FIX(val);
46
+ }
47
+
48
+ static inline VALUE cxx2ruby(double val) {
49
+ return rb_float_new(val);
50
+ }
51
+
52
+ /* Standard conversions for stdint-provided types */
53
+ /* TODO: replace these with something more comples but that properly
54
+ handle a try to convert a number too big to stay into the size
55
+ requested.
56
+ */
57
+ #define ruby2uint32_t ruby2uint
58
+ #define ruby2uint16_t ruby2uint
59
+ #define ruby2uint8_t ruby2uint
60
+
61
+ #define ruby2int32_t ruby2int
62
+ #define ruby2int16_t ruby2int
63
+ #define ruby2int8_t ruby2int
64
+
65
+ /* Conversion for common types (like strings */
66
+
67
+ static inline int *ruby2intArray(VALUE rval, int argn = -1) {
68
+ int i;
69
+ RArray *array = RARRAY(rval);
70
+ // int *ret = new int(array->len);
71
+ int ret[array->len];
72
+ for(i = 0; i < array->len; i++)
73
+ {
74
+ ret[i] = NUM2INT(array->ptr[i]);
75
+ }
76
+ return ret;
77
+ }
78
+
79
+ static inline char *ruby2charPtr(VALUE rval, int argn = -1) {
80
+ Check_Type(rval, T_STRING);
81
+ return StringValuePtr(rval);
82
+ }
83
+
84
+ static inline VALUE cxx2ruby(const char *val) {
85
+ if ( ! val ) return Qnil;
86
+ return rb_str_new2(val);
87
+ }
88
+
89
+ static inline VALUE cxx2ruby(const std::string &str) {
90
+ return rb_str_new2(str.c_str());
91
+ }
92
+
93
+ /* Booleans conversion */
94
+
95
+ static inline VALUE cxx2ruby(bool val) {
96
+ return val ? Qtrue : Qfalse;
97
+ }
98
+
99
+ static inline bool ruby2bool(VALUE rval, int argn = -1) {
100
+ return !( rval == Qnil || rval == Qfalse );
101
+ }
102
+
103
+ #endif
@@ -0,0 +1,67 @@
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 'pathname'
24
+
25
+ # Rust is a Ruby bindings generator, developed by Diego Pettenò
26
+ # <flameeyes@gmail.com>, based on a simpler Ruby bindings generator
27
+ # that was used for RubyTag++ and ruby-hunspell.
28
+ #
29
+ # The original bindings generator was designed to permit a 1:1 mapping
30
+ # between C++ classes and Ruby classes, as otherwise writing Ruby
31
+ # bindings for a C++-based library would have consisted of a long
32
+ # series of generic functions to convert the types from one language
33
+ # to the other and to call the methods.
34
+ #
35
+ # Most C bindings, instead, either writes a lot of C code to create
36
+ # "fake" Classes out of a vaguely object-oriented C API, or simply
37
+ # create a module where to put all the C functions to call.
38
+ #
39
+ # The objective of Rust is to allow the description of a C or C++
40
+ # interface, through the creation of 1:1 class mappings or the design
41
+ # of "fake" classes out of C functions, without the need to actually
42
+ # write all the generic code, as that does not really change beside
43
+ # names, types and parameters.
44
+ module Rust
45
+
46
+ # The Template singleton class is used to simulate a big hash of
47
+ # templates, loaded with the data from the templates/ subdirectory.
48
+ # In truth the templates are loaded only when requested, removing
49
+ # the one-line comments found inside the files (as they are usually
50
+ # just for documenting that particular template).
51
+ class Templates
52
+ @cache = { }
53
+ @tpls_dir = (Pathname.new File.dirname(__FILE__)) + "rust/templates"
54
+
55
+ def Templates.[](name)
56
+ return @cache[name].dup if @cache[name]
57
+
58
+ pn = @tpls_dir + "#{name}.rusttpl"
59
+ raise "Template #{name} not found." unless pn.exist?
60
+
61
+ @cache[name] = pn.read.gsub(/\/\/.*$\n?/, '')
62
+ return @cache[name].dup
63
+ end
64
+ end
65
+ end
66
+
67
+ require 'rust/bindings'
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2007 David Cuadrado <krawek@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
+ class Attribute < Element
29
+ def initialize(name, type, opts)
30
+ super()
31
+
32
+ @name = name
33
+ @type = Type.new(type)
34
+ @options = opts
35
+
36
+ @declaration_template = ""
37
+ @definition_template = Templates["AttributeDefinition"]
38
+ @prototype_template = "void set!attribute_bindname!(VALUE self, VALUE val);\nVALUE get!attribute_bindname!(VALUE self);\n"
39
+ @initialization_template = Templates["AttributeInitBinding"]
40
+
41
+
42
+ add_expansion 'parent_varname', "@options[:parent].varname"
43
+ add_expansion 'attribute_bindname', "@name"
44
+ add_expansion 'attribute_type', "@type"
45
+ add_expansion 'attribute_name', "@name"
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+
@@ -0,0 +1,172 @@
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 'rust/namespace'
24
+
25
+ module Rust
26
+ # Base class to use to create bindings for ruby.
27
+ # You shouldn't instantiate this manually, but rather use the
28
+ # create_bindings function.
29
+ class Bindings
30
+ # Constant to use with Bindings.create_bindings to state that the
31
+ # bindings that are to be created are for a C library.
32
+ LangC = "c"
33
+
34
+ # Constant to use with Bindings.create_bindings to state that the
35
+ # bindings that are to be created are for a C++ library.
36
+ LangCxx = "cxx"
37
+
38
+ # Constant to use with include_header method to state that the
39
+ # included header is a system library header.
40
+ HeaderGlobal = "global"
41
+
42
+ # Constant to use with include_header method to state that the
43
+ # included header is a local header.
44
+ HeaderLocal = "local"
45
+
46
+ def initialize(name, lang) # :notnew:
47
+ @name = name
48
+ @lang = lang
49
+
50
+ @modules = Array.new
51
+ @custom_definition = Array.new
52
+ @custom_initialization = Array.new
53
+
54
+ @cxx_includes = ""
55
+ @c_includes = ""
56
+ end
57
+
58
+ # This function is called when creating Ruby bindings for a
59
+ # library.
60
+ #
61
+ # The first parameter has to be one between Rust::Bindings::LangC
62
+ # or Rust::Bindings::LangCxx, and tells Rust which programming
63
+ # language the library to bind is written into.
64
+ #
65
+ # Please note that Rust always generates C++ code even when
66
+ # binding a library written in C, as STL templates are used all
67
+ # over the generics code.
68
+ def Bindings.create_bindings(lang, name)
69
+ bindings =
70
+ case lang
71
+ when Bindings::LangCxx, Bindings::LangC
72
+ bindings = Bindings.new(name, lang)
73
+ else
74
+ raise ArgumentError, "#{lang} is not a valid value for type parameter"
75
+ end
76
+
77
+ yield bindings
78
+
79
+ header = File.new("#{name}.hh", File::CREAT|File::TRUNC|File::RDWR)
80
+ unit = File.new("#{name}.cc", File::CREAT|File::TRUNC|File::RDWR)
81
+
82
+ header.puts bindings.header
83
+ unit.puts bindings.unit
84
+
85
+ header.close
86
+ unit.close
87
+ end
88
+
89
+ # Adds an include header with the specified name.
90
+ # This function adds to the list of header files to include the
91
+ # one with the specified name.
92
+ #
93
+ # If the scope paramether is set to Bindings.HeaderLocal, the name of
94
+ # the header file will be enclosed in double quotes ("") while
95
+ # including it, while it will be included it in angle quotes if
96
+ # the parameter is set to Bindings.HeaderGlobal (the default).
97
+ def include_header(name, scope = Bindings::HeaderGlobal, lang = @lang)
98
+ name =
99
+ case scope
100
+ when HeaderLocal then "\"#{name}\""
101
+ when HeaderGlobal then "<#{name}>"
102
+ else
103
+ raise ArgumentError, "#{scope} not a valid value for scope parameter."
104
+ end
105
+
106
+ case lang
107
+ when Bindings::LangCxx
108
+ @cxx_includes << "\n#include #{name}"
109
+ when Bindings::LangC
110
+ @c_includes << "\n#include #{name}"
111
+ end
112
+ end
113
+
114
+ # Binds a new Namespace to a Ruby module; the name parameter is
115
+ # used as the name of the module, while the cxxname one (if not
116
+ # null) is used to indicate the actual C++ namespace to use; when
117
+ # binding a C library, you should rather use the add_module
118
+ # function, although that's just a partial wrapper around this one.
119
+ def add_namespace(name, cxxname = nil)
120
+ cxxname = name if cxxname == nil
121
+
122
+ ns = Namespace.new(name, cxxname)
123
+
124
+ yield ns
125
+
126
+ @modules << ns
127
+ end
128
+
129
+ # Create a new Ruby module with the given name; this is used when
130
+ # binding C libraries, as they don't use namespace, so you have to
131
+ # create the modules from scratch.
132
+ def add_module(name)
133
+ add_namespace(name, "")
134
+ end
135
+
136
+ # Returns the content of the header for the bindings, recursively
137
+ # calling the proper functions to get the declarations for the
138
+ # modules bound and so on.
139
+ #
140
+ # This should *never* be used directly
141
+ def header
142
+ Templates["BindingsHeader"].
143
+ gsub("!bindings_name!", @name).
144
+ gsub("!modules_declaration!", @modules.collect { |ns| ns.declaration }.join("\n")).
145
+ gsub("!cxx_includes!", @cxx_includes).
146
+ gsub("!c_includes!", @c_includes)
147
+ end
148
+
149
+ # Returns the content of the unit for the bindings, recursively
150
+ # calling the proper functions to get the definitions and the
151
+ # initialisation function for the modules bound and so on.
152
+ #
153
+ # This should *never* be used directly
154
+ def unit
155
+ Templates["BindingsUnit"].
156
+ gsub("!bindings_name!", @name).
157
+ gsub("!modules_initialization!", @modules.collect { |ns| ns.initialization }.join("\n")).
158
+ gsub("!modules_definition!", @modules.collect { |ns| ns.definition }.join("\n")).
159
+ gsub("!custom_definition!", @custom_definition.join("\n")).
160
+ gsub("!custom_initialization!", @custom_initialization.join("\n"))
161
+ end
162
+
163
+ def add_custom_definition(element)
164
+ @custom_definition << element
165
+ end
166
+
167
+ def add_custom_initialization(initialization)
168
+ @custom_initialization << initialization
169
+ end
170
+ end
171
+
172
+ end
@@ -0,0 +1,334 @@
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 'rust/container'
24
+ require 'rust/function'
25
+ require 'rust/attribute'
26
+ require 'rust/type'
27
+
28
+ module Rust
29
+ class Class < Container
30
+ attr_accessor :bindname
31
+ attr_reader :name, :cname
32
+ attr_reader :varname, :varcname, :ptrmap, :function_free, :parent_varname
33
+
34
+ # Rust::Namespace object for the class, used to get the proper C++
35
+ # name.
36
+ attr_reader :namespace
37
+
38
+ # This function initializes the Class instance by setting the
39
+ # values to the attributes defining its namespace, name
40
+ # and a few other needed information.
41
+ #
42
+ # Don't call this function directly, use Namespace.add_cxx_class
43
+ def initialize(name, namespace, bindname = name.split("::").last ) # :notnew:
44
+ super()
45
+
46
+ @name = name
47
+ @namespace = namespace
48
+
49
+ type = Type.new(complete_name)
50
+ @varname = type.valid_name
51
+ @parent_varname = "rb_cObject"
52
+
53
+ @ptrmap = "#{type.valid_name}Map"
54
+ @function_free = "#{varname}_free"
55
+
56
+ @cname = @namespace.cname ? "#{@namespace.cname}::#{@name}" : @name
57
+
58
+ type = Type.new(@cname)
59
+ @varcname = type.valid_name
60
+ @bindname = bindname
61
+
62
+ @declaration_template = Templates["ClassDeclarations"]
63
+ @initialization_template = Templates["ClassInitialize"]
64
+
65
+ add_expansion 'class_varname', 'varname'
66
+ add_expansion 'class_varcname', 'varcname'
67
+ add_expansion 'c_class_name', 'cname'
68
+ # add_expansion 'c_class_basename', '@name.split("::").last'
69
+ add_expansion 'bind_name', '@bindname'
70
+ add_expansion 'class_ptrmap', 'ptrmap'
71
+ add_expansion 'class_free_function', '@function_free'
72
+ add_expansion 'parent_varname', '@parent_varname'
73
+ end
74
+
75
+ # Adds a new constructor for the class.
76
+ # This function creates a new constructor method for the C/C++
77
+ # class to bind, and yields it so that parameters can be added
78
+ # afterward.
79
+ def add_constructor
80
+ constructor = self.class::Constructor.new(self)
81
+
82
+ begin
83
+ yield constructor
84
+ rescue LocalJumpError
85
+ # Ignore this, we can easily have methods without parameters
86
+ # or other extra informations.
87
+ end if block_given?
88
+
89
+ register_function(constructor)
90
+
91
+ return constructor
92
+ end
93
+
94
+ # Adds a new method for the class.
95
+ # This function adds a new generic method for the class. In the
96
+ # case of C++ classes, this is an actual method of the bound
97
+ # class, while in case of Class Wrappers, this is just a function
98
+ # that expects to find a static parameter that is the instance
99
+ # pointer itself.
100
+ def add_method(name, return_value = "void", bindname = name)
101
+ method = self.class::Method.new({ :name => name,
102
+ :bindname => bindname,
103
+ :return => return_value,
104
+ :klass => self
105
+ })
106
+
107
+ begin
108
+ yield method
109
+ rescue LocalJumpError
110
+ # Ignore this, we can easily have methods without parameters
111
+ # or other extra informations.
112
+ end if block_given?
113
+
114
+ register_function(method)
115
+
116
+ method
117
+ end
118
+
119
+ def add_attribute(name, type, bindname = name)
120
+ attribute = Attribute.new(name, type, { :parent => self })
121
+
122
+ yield attribute if block_given?
123
+
124
+ @children << attribute
125
+
126
+ attribute
127
+ end
128
+
129
+ def add_operator(name, return_value, bindname = name)
130
+ operator = Class::Operator.new({ :name => name,
131
+ :bindname => bindname,
132
+ :return => return_value,
133
+ :klass => self
134
+ })
135
+ begin
136
+ yield operator
137
+ rescue LocalJumpError
138
+ end if block_given?
139
+
140
+ register_function(operator)
141
+
142
+
143
+ return operator
144
+ end
145
+
146
+ def complete_name
147
+ name = @name
148
+ parent = @parent
149
+ namespace = @namespace
150
+
151
+ if not parent.nil?
152
+ name = "#{parent.cname}::#{name}"
153
+ end
154
+
155
+ if not namespace.nil?
156
+ name = "#{namespace.cname}::#{name}"
157
+ end
158
+
159
+ return name if parent.nil?
160
+
161
+ while not parent.parent.nil?
162
+ name = "#{parent.parent.cname}::#{name}"
163
+ parent = parent.parent
164
+ end
165
+
166
+ return name if namespace.nil?
167
+
168
+ while not namespace.parent.nil?
169
+ name = "#{namespace.parent.cname}::#{name}"
170
+ namespace = namespace.parent
171
+ end
172
+
173
+ name
174
+ end
175
+
176
+ # Adds a new variable for the class. It's not an actual variable,
177
+ # as hopefully there aren't global or class public variables in
178
+ # any library.
179
+ # These virtual variables have setter and getter methods, usually
180
+ # called 'var' and 'setVar' in C++ (or 'getVar' and 'setVar'), and
181
+ # are mapped to 'var' and 'var=' in Ruby, so that setting the
182
+ # variable in Ruby will just call the setter method.
183
+ def add_variable(name, type, getter = nil, setter = nil)
184
+ getter = name unless getter
185
+ setter = "set" + name[0..0].capitalize + name[1..-1] unless
186
+ setter
187
+
188
+ method_get = add_method getter, type
189
+ method_get.add_alias name
190
+
191
+ method_set = add_method setter, "void"
192
+ method_set.add_alias "#{name}="
193
+
194
+ begin
195
+ yield method_get, method_set
196
+ rescue LocalJumpError
197
+ # Ignore this, we can easily have methods without parameters
198
+ # or other extra informations.
199
+ end if block_given?
200
+
201
+ method_set.add_parameter type, "value"
202
+
203
+ return [method_get, method_set]
204
+ end
205
+
206
+ # This class is used to represent a method for a C/C++ class bound
207
+ # in a Ruby extension. Through an object of this class you can add
208
+ # parameters and more to the method.
209
+ class Method < Function
210
+
211
+ # Initialisation function, calls Function.initialize and sets
212
+ # the important parameters that differs from a generic function
213
+ def initialize(params) # :notnew:
214
+ params[:parent] = params[:klass]
215
+ super
216
+
217
+ @varname =
218
+ "f#{@parent.namespace.name.gsub("::","_")}_#{@parent.name}_#{@name}"
219
+
220
+ @definition_template = Templates["CxxMethodStub"]
221
+ @initialization_template = Templates["MethodInitBinding"]
222
+ end
223
+ end
224
+
225
+ class Operator < Function
226
+ attr_reader :position # 1: pre 2: mid 3: post 4: mixed
227
+
228
+ def initialize(params)
229
+ params[:parent] = params[:klass]
230
+ super
231
+
232
+ type = Type.new(@parent.namespace.cname+"::"+@parent.cname)
233
+
234
+ @varname = "f#{type.valid_name}_#{valid_name}"
235
+
236
+ @definition_template = Templates["CxxMethodStub"]
237
+ @initialization_template = Templates["MethodInitBinding"]
238
+ end
239
+
240
+ def bind_call(nparam = nil)
241
+ case @return
242
+ when nil
243
+ raise "nil return value is not supported for non-constructors."
244
+ when "void"
245
+ return "#{raw_call(nparam)}; return Qnil;\n"
246
+ else
247
+ type = Type.new(@return)
248
+ if not @return.include?("*") and not type.native?
249
+ "return cxx2ruby( new #{@return.gsub("&", "")}(#{raw_call(nparam)}), true );\n" # XXX: needs a copy constructor
250
+ else
251
+ "return cxx2ruby( static_cast<#{@return}>(#{raw_call(nparam)}) );\n"
252
+ end
253
+ end
254
+ end
255
+
256
+ private
257
+ def raw_call(nparam = nil)
258
+ case @position
259
+ when 1 # pre
260
+ "#{@name} (*tmp)"
261
+ when 2 # mid
262
+ "(*tmp) #{@name[0].chr} #{params_conversion(nparam)} #{@name[@name.length-1].chr} "
263
+ when 4
264
+ "(*tmp) #{@name[0].chr} #{self.parameters[0].conversion} #{@name[1].chr} #{@name[@name.length-1].chr} #{self.parameters[1].conversion}" if self.parameters.size == 2
265
+ else
266
+ "(*tmp) #{@name} #{params_conversion(nparam)} "
267
+ end
268
+ end
269
+
270
+ def valid_name
271
+ case @name
272
+ when "+"
273
+ @position = 3
274
+ "plusop"
275
+ when "-"
276
+ @position = 3
277
+ "minusop"
278
+ when "*"
279
+ @position = 3
280
+ "multop"
281
+ when "/"
282
+ @position = 3
283
+ "divop"
284
+ when /\[\s*\]=/
285
+ @position = 4
286
+ "ateqop"
287
+ when /\[\s*\]/
288
+ @position = 2
289
+ "atop"
290
+ when "=="
291
+ @position = 3
292
+ "equalop"
293
+ when "!="
294
+ @position = 3
295
+ "notequalop"
296
+ when "<<"
297
+ @position = 3
298
+ "outstream"
299
+ when ">>"
300
+ @position = 3
301
+ "intstream"
302
+ when "!"
303
+ @position = 1
304
+ "notop"
305
+ else
306
+ @position = 3
307
+ "undefop_#{@name[0].chr.to_i}#{rand(1024)}"
308
+ end
309
+ end
310
+ end
311
+
312
+ # This class is used to represente the constructor of a C++ class
313
+ # bound in a Ruby extension.
314
+ class Constructor < Function
315
+
316
+ # Initialisation function, calls Function.initialise, but accepts
317
+ # only a single parameter, the class the constructor belong to.
318
+ def initialize(klass) # :notnew:
319
+ super({
320
+ :parent => klass,
321
+ :bindname => "initialize",
322
+ :name => klass.name
323
+ })
324
+
325
+ @definition_template = Templates["ConstructorStub"]
326
+ end
327
+
328
+ def bind_call(nparam = nil)
329
+ "#{raw_call(nparam)};\n"
330
+ end
331
+ end
332
+
333
+ end
334
+ end