dub 0.5.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.

Potentially problematic release.


This version of dub might be problematic. Click here for more details.

Files changed (142) hide show
  1. data/.gitignore +8 -0
  2. data/History.txt +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +53 -0
  5. data/Rakefile +58 -0
  6. data/dub.gemspec +194 -0
  7. data/lib/dub/argument.rb +261 -0
  8. data/lib/dub/entities_unescape.rb +16 -0
  9. data/lib/dub/function.rb +111 -0
  10. data/lib/dub/function_group.rb +74 -0
  11. data/lib/dub/generator.rb +15 -0
  12. data/lib/dub/group.rb +10 -0
  13. data/lib/dub/klass.rb +231 -0
  14. data/lib/dub/lua/class.cpp.erb +75 -0
  15. data/lib/dub/lua/class_gen.rb +78 -0
  16. data/lib/dub/lua/function.cpp.erb +4 -0
  17. data/lib/dub/lua/function_gen.rb +223 -0
  18. data/lib/dub/lua/group.cpp.erb +10 -0
  19. data/lib/dub/lua/lua_cpp_helper.h +141 -0
  20. data/lib/dub/lua/namespace.cpp.erb +35 -0
  21. data/lib/dub/lua/namespace_gen.rb +86 -0
  22. data/lib/dub/lua.rb +24 -0
  23. data/lib/dub/member_extraction.rb +88 -0
  24. data/lib/dub/namespace.rb +276 -0
  25. data/lib/dub/parser.rb +46 -0
  26. data/lib/dub/templates/lua_template.erb +21 -0
  27. data/lib/dub/version.rb +3 -0
  28. data/lib/dub.rb +26 -0
  29. data/test/argument_test.rb +423 -0
  30. data/test/fixtures/app/CMakeLists.txt +54 -0
  31. data/test/fixtures/app/Doxyfile +1600 -0
  32. data/test/fixtures/app/bindings/all_lua.cpp +299 -0
  33. data/test/fixtures/app/include/matrix.h +123 -0
  34. data/test/fixtures/app/make_lua_bindings.rb +13 -0
  35. data/test/fixtures/app/vendor/lua/CMakeLists.txt +25 -0
  36. data/test/fixtures/app/vendor/lua/COPYRIGHT +34 -0
  37. data/test/fixtures/app/vendor/lua/HISTORY +183 -0
  38. data/test/fixtures/app/vendor/lua/INSTALL +99 -0
  39. data/test/fixtures/app/vendor/lua/Makefile +183 -0
  40. data/test/fixtures/app/vendor/lua/README +37 -0
  41. data/test/fixtures/app/vendor/lua/lapi.c +1080 -0
  42. data/test/fixtures/app/vendor/lua/lapi.h +16 -0
  43. data/test/fixtures/app/vendor/lua/lauxlib.c +653 -0
  44. data/test/fixtures/app/vendor/lua/lauxlib.h +174 -0
  45. data/test/fixtures/app/vendor/lua/lbaselib.c +643 -0
  46. data/test/fixtures/app/vendor/lua/lcode.c +839 -0
  47. data/test/fixtures/app/vendor/lua/lcode.h +76 -0
  48. data/test/fixtures/app/vendor/lua/ldblib.c +397 -0
  49. data/test/fixtures/app/vendor/lua/ldebug.c +622 -0
  50. data/test/fixtures/app/vendor/lua/ldebug.h +33 -0
  51. data/test/fixtures/app/vendor/lua/ldo.c +516 -0
  52. data/test/fixtures/app/vendor/lua/ldo.h +57 -0
  53. data/test/fixtures/app/vendor/lua/ldump.c +164 -0
  54. data/test/fixtures/app/vendor/lua/lfunc.c +174 -0
  55. data/test/fixtures/app/vendor/lua/lfunc.h +34 -0
  56. data/test/fixtures/app/vendor/lua/lgc.c +711 -0
  57. data/test/fixtures/app/vendor/lua/lgc.h +110 -0
  58. data/test/fixtures/app/vendor/lua/liblua.a +0 -0
  59. data/test/fixtures/app/vendor/lua/linit.c +38 -0
  60. data/test/fixtures/app/vendor/lua/liolib.c +532 -0
  61. data/test/fixtures/app/vendor/lua/llex.c +461 -0
  62. data/test/fixtures/app/vendor/lua/llex.h +81 -0
  63. data/test/fixtures/app/vendor/lua/llimits.h +128 -0
  64. data/test/fixtures/app/vendor/lua/lmathlib.c +263 -0
  65. data/test/fixtures/app/vendor/lua/lmem.c +86 -0
  66. data/test/fixtures/app/vendor/lua/lmem.h +49 -0
  67. data/test/fixtures/app/vendor/lua/loadlib.c +664 -0
  68. data/test/fixtures/app/vendor/lua/lobject.c +214 -0
  69. data/test/fixtures/app/vendor/lua/lobject.h +381 -0
  70. data/test/fixtures/app/vendor/lua/lopcodes.c +102 -0
  71. data/test/fixtures/app/vendor/lua/lopcodes.h +268 -0
  72. data/test/fixtures/app/vendor/lua/loslib.c +244 -0
  73. data/test/fixtures/app/vendor/lua/lparser.c +1337 -0
  74. data/test/fixtures/app/vendor/lua/lparser.h +82 -0
  75. data/test/fixtures/app/vendor/lua/lstate.c +214 -0
  76. data/test/fixtures/app/vendor/lua/lstate.h +168 -0
  77. data/test/fixtures/app/vendor/lua/lstring.c +111 -0
  78. data/test/fixtures/app/vendor/lua/lstring.h +31 -0
  79. data/test/fixtures/app/vendor/lua/lstrlib.c +868 -0
  80. data/test/fixtures/app/vendor/lua/ltable.c +588 -0
  81. data/test/fixtures/app/vendor/lua/ltable.h +40 -0
  82. data/test/fixtures/app/vendor/lua/ltablib.c +278 -0
  83. data/test/fixtures/app/vendor/lua/ltm.c +75 -0
  84. data/test/fixtures/app/vendor/lua/ltm.h +54 -0
  85. data/test/fixtures/app/vendor/lua/lua.c +695 -0
  86. data/test/fixtures/app/vendor/lua/lua.h +385 -0
  87. data/test/fixtures/app/vendor/lua/lua_dub_helper.h +77 -0
  88. data/test/fixtures/app/vendor/lua/luac +0 -0
  89. data/test/fixtures/app/vendor/lua/luac.c +200 -0
  90. data/test/fixtures/app/vendor/lua/luaconf.h +762 -0
  91. data/test/fixtures/app/vendor/lua/lualib.h +53 -0
  92. data/test/fixtures/app/vendor/lua/lundump.c +223 -0
  93. data/test/fixtures/app/vendor/lua/lundump.h +36 -0
  94. data/test/fixtures/app/vendor/lua/lvm.c +765 -0
  95. data/test/fixtures/app/vendor/lua/lvm.h +36 -0
  96. data/test/fixtures/app/vendor/lua/lzio.c +82 -0
  97. data/test/fixtures/app/vendor/lua/lzio.h +67 -0
  98. data/test/fixtures/app/vendor/lua/matrix.h +102 -0
  99. data/test/fixtures/app/vendor/lua/print.c +227 -0
  100. data/test/fixtures/app/vendor/lua/test/README +26 -0
  101. data/test/fixtures/app/vendor/lua/test/bisect.lua +27 -0
  102. data/test/fixtures/app/vendor/lua/test/cf.lua +16 -0
  103. data/test/fixtures/app/vendor/lua/test/echo.lua +5 -0
  104. data/test/fixtures/app/vendor/lua/test/env.lua +7 -0
  105. data/test/fixtures/app/vendor/lua/test/factorial.lua +32 -0
  106. data/test/fixtures/app/vendor/lua/test/fib.lua +40 -0
  107. data/test/fixtures/app/vendor/lua/test/fibfor.lua +13 -0
  108. data/test/fixtures/app/vendor/lua/test/globals.lua +13 -0
  109. data/test/fixtures/app/vendor/lua/test/hello.lua +3 -0
  110. data/test/fixtures/app/vendor/lua/test/life.lua +111 -0
  111. data/test/fixtures/app/vendor/lua/test/luac.lua +7 -0
  112. data/test/fixtures/app/vendor/lua/test/printf.lua +7 -0
  113. data/test/fixtures/app/vendor/lua/test/readonly.lua +12 -0
  114. data/test/fixtures/app/vendor/lua/test/sieve.lua +29 -0
  115. data/test/fixtures/app/vendor/lua/test/sort.lua +66 -0
  116. data/test/fixtures/app/vendor/lua/test/table.lua +12 -0
  117. data/test/fixtures/app/vendor/lua/test/trace-calls.lua +32 -0
  118. data/test/fixtures/app/vendor/lua/test/trace-globals.lua +38 -0
  119. data/test/fixtures/app/vendor/lua/test/xd.lua +14 -0
  120. data/test/fixtures/app/xml/classdub_1_1_matrix.xml +239 -0
  121. data/test/fixtures/app/xml/classdub_1_1_t_mat.xml +233 -0
  122. data/test/fixtures/app/xml/combine.xslt +15 -0
  123. data/test/fixtures/app/xml/compound.xsd +814 -0
  124. data/test/fixtures/app/xml/dir_53661a2bdeb1d55e60581a7e15deb763.xml +12 -0
  125. data/test/fixtures/app/xml/index.xml +42 -0
  126. data/test/fixtures/app/xml/index.xsd +66 -0
  127. data/test/fixtures/app/xml/matrix_8h.xml +149 -0
  128. data/test/fixtures/app/xml/namespacedub.xml +41 -0
  129. data/test/fixtures/classcv_1_1_mat.xml +1996 -0
  130. data/test/fixtures/classcv_1_1_point__.xml +341 -0
  131. data/test/fixtures/classcv_1_1_size__.xml +270 -0
  132. data/test/fixtures/group___magic_type.xml +406 -0
  133. data/test/fixtures/namespacecv.xml +12659 -0
  134. data/test/function_group_test.rb +15 -0
  135. data/test/function_test.rb +252 -0
  136. data/test/group_test.rb +155 -0
  137. data/test/helper.rb +34 -0
  138. data/test/klass_test.rb +297 -0
  139. data/test/lua_function_gen_test.rb +179 -0
  140. data/test/namespace_test.rb +220 -0
  141. data/test/parser_test.rb +36 -0
  142. metadata +216 -0
@@ -0,0 +1,111 @@
1
+ require 'dub/argument'
2
+ require 'dub/entities_unescape'
3
+
4
+ module Dub
5
+ class Function
6
+ include Dub::EntitiesUnescape
7
+ attr_reader :arguments, :prefix, :overloaded_index, :return_value, :xml, :parent
8
+ attr_accessor :gen, :name, :is_constructor
9
+
10
+ def initialize(parent, name, xml, prefix = '', overloaded_index = nil)
11
+ @parent, @name = parent, name
12
+ @xml, @prefix, @overloaded_index = xml, prefix, overloaded_index
13
+ parse_xml
14
+ end
15
+
16
+ def set_as_constructor
17
+ @return_value = Argument.new(self, (Hpricot::XML("<type>#{name} *</type>")/''))
18
+ @is_constructor = true
19
+ end
20
+
21
+ def bind(generator)
22
+ @gen = generator.function_generator
23
+ end
24
+
25
+ def to_s
26
+ generator.function(self)
27
+ end
28
+
29
+ def generator
30
+ @gen || (@parent && @parent.function_generator)
31
+ end
32
+
33
+ def klass
34
+ @parent.kind_of?(Klass) ? @parent : nil
35
+ end
36
+
37
+ def member_method?
38
+ !klass.nil?
39
+ end
40
+
41
+ def constructor?
42
+ @is_constructor
43
+ end
44
+
45
+ alias gen generator
46
+
47
+ def name=(n)
48
+ @name = n
49
+ if constructor?
50
+ @return_value.type = n
51
+ end
52
+ end
53
+
54
+ def source
55
+ loc = (@xml/'location').first.attributes
56
+ "#{loc['file'].split('/')[-3..-1].join('/')}:#{loc['line']}"
57
+ end
58
+
59
+ def original_signature
60
+ unescape "#{(@xml/'definition').innerHTML}#{(@xml/'argsstring').innerHTML}"
61
+ end
62
+
63
+ def has_default_arguments?
64
+ return @has_defaults if defined?(@has_defaults)
65
+ @has_defaults = !@arguments.detect {|a| a.has_default? }.nil?
66
+ end
67
+
68
+ def has_array_arguments?
69
+ return @has_array_arguments if defined?(@has_array_arguments)
70
+ @has_array_arguments = !@arguments.detect {|a| a.array_suffix }.nil?
71
+ end
72
+
73
+ def vararg?
74
+ @arguments.last && @arguments.last.vararg?
75
+ end
76
+
77
+ def inspect
78
+ "#<Function #{@prefix}_#{@name}(#{@arguments.inspect[1..-2]})>"
79
+ end
80
+
81
+ def <=>(other)
82
+ name <=> other.name
83
+ end
84
+
85
+ # ====== these methods are alias to
86
+ # generator methods on this object
87
+
88
+ def method_name(overloaded_index = nil)
89
+ gen.method_name(self, overloaded_index)
90
+ end
91
+
92
+ # =================================
93
+
94
+ private
95
+ def parse_xml
96
+ @arguments = []
97
+
98
+ (@xml/'param').each_with_index do |arg, i|
99
+ @arguments << Argument.new(self, arg, i + 1)
100
+ end
101
+
102
+ raw_type = (@xml/'/type').innerHTML
103
+ if raw_type.strip == ''
104
+ # no return type
105
+ else
106
+ arg = Argument.new(self, (@xml/'/type'))
107
+ @return_value = arg unless arg.create_type =~ /void\s*$/
108
+ end
109
+ end
110
+ end
111
+ end # Namespace
@@ -0,0 +1,74 @@
1
+ module Dub
2
+ class FunctionGroup < Array
3
+ def initialize(parent, gen = nil)
4
+ @parent, @gen = parent, gen
5
+ end
6
+
7
+ def bind(generator)
8
+ self.gen = generator.function_generator
9
+ end
10
+
11
+ def generator
12
+ @gen || (@parent && @parent.function_generator)
13
+ end
14
+
15
+ def gen=(generator)
16
+ @gen = generator
17
+ @gen_members = nil
18
+ end
19
+
20
+ alias gen generator
21
+
22
+ def members
23
+ if self.generator
24
+ if @parent.generator
25
+ @gen_members ||= @parent.generator.members_list(self)
26
+ else
27
+ @gen_members ||= generator.namespace_generator.members_list(self)
28
+ end
29
+ else
30
+ self
31
+ end
32
+ end
33
+
34
+ def to_s
35
+ generator.group(self)
36
+ end
37
+
38
+ def name
39
+ first.name
40
+ end
41
+
42
+ def method_name(overloaded_index = nil)
43
+ first.method_name(overloaded_index)
44
+ end
45
+
46
+ def map(&block)
47
+ list = self.class.new(@parent, @gen)
48
+ super(&block).each do |e|
49
+ list << e
50
+ end
51
+ list
52
+ end
53
+
54
+ def compact
55
+ list = self.class.new(@parent, @gen)
56
+ super.each do |e|
57
+ list << e
58
+ end
59
+ list
60
+ end
61
+
62
+ def overloaded_index
63
+ nil
64
+ end
65
+
66
+ def prefix
67
+ first.prefix
68
+ end
69
+
70
+ def <=>(other)
71
+ name <=> other.name
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,15 @@
1
+ require 'dub/function'
2
+
3
+ module Dub
4
+ class Generator
5
+
6
+ def comment(func)
7
+ "/** #{func.original_signature}\n * #{func.source}\n */"
8
+ end
9
+
10
+ protected
11
+ def indent(str, indent)
12
+ str.gsub(/^/, ' ' * indent)
13
+ end
14
+ end # Generator
15
+ end # Dub
data/lib/dub/group.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'dub/namespace'
2
+
3
+ module Dub
4
+ class Group < Namespace
5
+ def parse_xml
6
+ super
7
+ parse_defines
8
+ end
9
+ end
10
+ end
data/lib/dub/klass.rb ADDED
@@ -0,0 +1,231 @@
1
+ module Dub
2
+ module MemberExtraction
3
+ end
4
+ end
5
+ require 'dub/member_extraction'
6
+
7
+ module Dub
8
+ class Klass
9
+ include MemberExtraction
10
+ attr_reader :name, :xml, :prefix, :constructor, :alias_names, :enums, :parent, :instanciations
11
+ attr_accessor :header
12
+
13
+ def initialize(parent, name, xml, prefix = '')
14
+ @parent, @name, @xml, @prefix = parent, name, xml, prefix
15
+
16
+ @alias_names = []
17
+ @enums = []
18
+ @ignores = []
19
+ @instanciations = {}
20
+ parse_xml
21
+ end
22
+
23
+ def bind(generator)
24
+ self.gen = generator.class_generator
25
+ end
26
+
27
+ def gen=(generator)
28
+ @gen = generator
29
+ @gen_members = nil
30
+ end
31
+
32
+ def to_s
33
+ generator.klass(self)
34
+ end
35
+
36
+ def generator
37
+ @gen || (@parent && @parent.class_generator)
38
+ end
39
+
40
+ def function_generator
41
+ if generator = self.generator
42
+ generator.function_generator
43
+ else
44
+ nil
45
+ end
46
+ end
47
+
48
+ alias gen generator
49
+
50
+ def ignore(list)
51
+ list = [list].flatten
52
+ @ignores += list
53
+ @ignores.uniq!
54
+ @gen_members = nil
55
+ end
56
+
57
+ def members
58
+ if self.generator
59
+ @gen_members ||= self.generator.members_list(super, @ignores)
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ def <=>(other)
66
+ name <=> other.name
67
+ end
68
+
69
+ def [](name)
70
+ name.to_s == @name ? constructor : get_member(name.to_s)
71
+ end
72
+
73
+ def class_methods
74
+ []
75
+ end
76
+
77
+ def template?
78
+ !@template_params.nil?
79
+ end
80
+
81
+ def has_constants?
82
+ has_enums?
83
+ end
84
+
85
+ def has_enums?
86
+ !@enums.empty?
87
+ end
88
+
89
+ def template_params
90
+ @template_params
91
+ end
92
+
93
+ def class_with_params(template_params)
94
+ @instanciations[template_params]
95
+ end
96
+
97
+ def register_instanciation(template_params, klass)
98
+ @instanciations[template_params] = klass
99
+ end
100
+
101
+ def source
102
+ loc = (@xml/'location').first.attributes
103
+ "#{loc['file'].split('/')[-3..-1].join('/')}:#{loc['line']}"
104
+ end
105
+
106
+ def header
107
+ @header ||= (@xml/'location').first.attributes['file'].split('/').last
108
+ end
109
+
110
+ def full_type
111
+ @parent ? "#{@parent.full_type}::#{name}" : name
112
+ end
113
+
114
+ def lib_name
115
+ "#{prefix}_#{name}"
116
+ end
117
+
118
+ def id_name(name = self.name)
119
+ "#{prefix}.#{name}"
120
+ end
121
+
122
+ def destructor_name
123
+ "#{name}_destructor"
124
+ end
125
+
126
+ def tostring_name
127
+ "#{name}__tostring"
128
+ end
129
+
130
+ def constructor
131
+ if defined?(@constructor)
132
+ @constructor
133
+ else
134
+ self.members
135
+ @constructor ||= nil
136
+ end
137
+ @constructor
138
+ end
139
+
140
+ def names
141
+ [@name] + @alias_names
142
+ end
143
+
144
+ private
145
+ def parse_xml
146
+ parse_enums
147
+ parse_members
148
+ parse_template_params
149
+ parse_instanciations
150
+ parse_alias_names
151
+ end
152
+
153
+ def parse_enums
154
+ @enums = (@xml/"enumvalue/name").map{|e| e.innerHTML}
155
+ end
156
+
157
+ def parse_template_params
158
+ template_params = (@xml/'/templateparamlist/param')
159
+ if !template_params.empty?
160
+ @template_params = template_params.map do |param|
161
+ (param/'/type').innerHTML.gsub(/^\s*(typename|class)\s+/,'')
162
+ end
163
+ end
164
+ end
165
+
166
+ def parse_instanciations
167
+ (@xml/'instanciation').each do |klass|
168
+ name = (klass/'name').innerHTML
169
+ params = (klass/'param').map do |p|
170
+ p.innerHTML
171
+ end
172
+
173
+ @instanciations[params] = @parent[name]
174
+ end
175
+ end
176
+
177
+ def parse_alias_names
178
+ (@xml/'aliases/name').each do |name|
179
+ name = name.innerHTML
180
+ if name.size < @name.size
181
+ @alias_names << @name
182
+ change_name(name)
183
+ else
184
+ @alias_names << name
185
+ end
186
+
187
+ if @parent
188
+ @parent.register_alias(name, self)
189
+ end
190
+ end
191
+ end
192
+
193
+ def make_member(name, member, overloaded_index = nil)
194
+ if names.include?(name)
195
+ # keep constructors out of members list
196
+ if @constructor.kind_of?(FunctionGroup)
197
+ constr = super
198
+ constr.name = @name # force key name
199
+ constr.set_as_constructor
200
+ @constructor << constr
201
+ elsif @constructor
202
+ constr = super
203
+ constr.name = @name
204
+ constr.set_as_constructor
205
+ list = Dub::FunctionGroup.new(self)
206
+ list << @constructor
207
+ list << constr
208
+ @constructor = list
209
+ else
210
+ @constructor = super
211
+ @constructor.set_as_constructor
212
+ @constructor.name = @name
213
+ end
214
+ nil
215
+ else
216
+ super
217
+ end
218
+ end
219
+
220
+ def change_name(new_name)
221
+ @name = new_name
222
+ if @constructor.kind_of?(Array)
223
+ @constructor.each do |c|
224
+ c.name = new_name
225
+ end
226
+ elsif @constructor
227
+ @constructor.name = new_name
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,75 @@
1
+ #include "<%= @class.header %>"
2
+
3
+ #include "lua_cpp_helper.h"
4
+
5
+ <% if @class.prefix %>
6
+ using namespace <%= @class.prefix %>;
7
+ <% end %>
8
+
9
+ /* ============================ Constructors ====================== */
10
+
11
+ <%= @class.constructor %>
12
+
13
+ /* ============================ Destructor ====================== */
14
+
15
+ static int <%= @class.destructor_name %>(lua_State *L) {
16
+ <%= @class.name %> **userdata = (<%= @class.name %>**)luaL_checkudata(L, 1, <%= @class.id_name.inspect %>);
17
+ if (*userdata) delete *userdata;
18
+ *userdata = NULL;
19
+ return 0;
20
+ }
21
+
22
+ /* ============================ tostring ====================== */
23
+
24
+ static int <%= @class.tostring_name %>(lua_State *L) {
25
+ <%= @class.name %> **userdata = (<%= @class.name %>**)luaL_checkudata(L, 1, <%= @class.id_name.inspect %>);
26
+ lua_pushfstring(L, "<%= @class.id_name %>: %p", *userdata);
27
+ return 1;
28
+ }
29
+
30
+ /* ============================ Member Methods ====================== */
31
+
32
+ <% if @class.members; @class.members.each do |function| %>
33
+ <%= function %>
34
+
35
+ <% end; end %>
36
+
37
+
38
+ /* ============================ Lua Registration ====================== */
39
+
40
+ static const struct luaL_Reg <%= @class.name %>_member_methods[] = {
41
+ <%= indent(method_registration, 2) %>,
42
+ {NULL, NULL},
43
+ };
44
+
45
+ static const struct luaL_Reg <%= @class.name %>_namespace_methods[] = {
46
+ <%= indent(namespace_methods_registration, 2) %>,
47
+ {NULL, NULL},
48
+ };
49
+
50
+ <% if @class.has_constants? %>
51
+ static const struct lua_constants_Reg <%= @class.name %>_namespace_constants[] = {
52
+ <%= indent(constants_registration, 2) %>,
53
+ {NULL, NULL},
54
+ };
55
+ <% end %>
56
+
57
+ void luaopen_<%= @class.lib_name %>(lua_State *L) {
58
+ // Create the metatable which will contain all the member methods
59
+ luaL_newmetatable(L, <%= @class.id_name.inspect %>); // "dub.Matrix"
60
+
61
+ // metatable.__index = metatable (find methods in the table itself)
62
+ lua_pushvalue(L, -1);
63
+ lua_setfield(L, -2, "__index");
64
+
65
+ // register member methods
66
+ luaL_register(L, NULL, <%= @class.name %>_member_methods);
67
+
68
+ // register class methods in a global table like "dub"
69
+ luaL_register(L, <%= @class.prefix.inspect %>, <%= @class.name %>_namespace_methods);
70
+
71
+ <% if @class.has_constants? %>
72
+ // register class enums
73
+ register_constants(L, <%= (@class.id_name + '_const').inspect %>, <%= @class.name %>_namespace_constants);
74
+ <% end %>
75
+ }
@@ -0,0 +1,78 @@
1
+
2
+ require 'dub/generator'
3
+ require 'erb'
4
+
5
+ module Dub
6
+ module Lua
7
+ class ClassGen < Dub::Generator
8
+ def initialize
9
+ @class_template = ::ERB.new(File.read(File.join(File.dirname(__FILE__), 'class.cpp.erb')))
10
+ end
11
+
12
+ def klass(klass)
13
+ @class = klass
14
+ @class_template.result(binding)
15
+ end
16
+
17
+ def function_generator
18
+ Lua.function_generator
19
+ end
20
+
21
+ def method_registration(klass = @class)
22
+ member_methods = (klass.members || []).map do |method|
23
+ "{%-20s, #{method.method_name(0)}}" % method.name.inspect
24
+ end
25
+
26
+ member_methods << "{%-20s, #{klass.tostring_name}}" % "__tostring".inspect
27
+ member_methods << "{%-20s, #{klass.destructor_name}}" % "__gc".inspect
28
+
29
+ member_methods.join(",\n")
30
+ end
31
+
32
+ def namespace_methods_registration
33
+ @class.names.map do |name|
34
+ "{%-20s, #{@class.constructor.method_name(0)}}" % name.inspect
35
+ end.join(",\n")
36
+ end
37
+
38
+ def constants_registration(klass = @class)
39
+ klass.enums.map do |name|
40
+ "{%-20s, #{klass.full_type}::#{name}}" % name.inspect
41
+ end.join(",\n")
42
+ end
43
+
44
+ def members_list(all_members, ignore_list = [])
45
+ list = all_members.map do |member_or_group|
46
+ if ignore_list.include?(member_or_group.name)
47
+ nil
48
+ elsif member_or_group.kind_of?(Array)
49
+ members_list(member_or_group)
50
+ elsif ignore_member?(member_or_group)
51
+ nil
52
+ else
53
+ member_or_group
54
+ end
55
+ end
56
+
57
+ list.compact!
58
+ list == [] ? nil : list
59
+ end
60
+
61
+ def ignore_member?(member)
62
+ if member.name =~ /^~/ || # do not build constructor
63
+ member.name =~ /^operator/ || # no conversion operators
64
+ member.original_signature =~ />/ || # no complex types in signature
65
+ member.has_array_arguments? ||
66
+ member.vararg? ||
67
+ member.original_signature =~ /void\s+\*/
68
+ true # ignore
69
+ elsif return_value = member.return_value
70
+ return_value.type =~ />$/ || # no complex return types
71
+ return_value.is_native? && member.return_value.is_pointer?
72
+ else
73
+ false # ok, do not ignore
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,4 @@
1
+ <%= comment(@function) %>
2
+ <%= signature(@function) %> {
3
+ <%= indent(body(@function), 2) %>
4
+ }