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,276 @@
1
+ require 'dub/member_extraction'
2
+
3
+ module Dub
4
+
5
+ class Namespace
6
+ include MemberExtraction
7
+ attr_accessor :name, :gen, :xml, :enums, :parent, :header, :prefix, :defines
8
+
9
+ def initialize(name, xml, current_dir)
10
+ @name, @xml, @current_dir = name, xml, current_dir
11
+ @class_alias = {}
12
+ @alias_names = []
13
+ @enums = []
14
+ @defines = []
15
+ @ignores = []
16
+ parse_xml
17
+ end
18
+
19
+ def bind(generator)
20
+ self.gen = generator.namespace_generator
21
+ end
22
+
23
+ def gen=(generator)
24
+ @gen = generator
25
+ @gen_members = nil
26
+ end
27
+
28
+ def generator
29
+ @gen
30
+ end
31
+
32
+ def class_generator
33
+ @gen && @gen.class_generator
34
+ end
35
+
36
+ def function_generator
37
+ @gen && @gen.function_generator
38
+ end
39
+
40
+ alias gen generator
41
+
42
+ def to_s
43
+ @gen.namespace(self)
44
+ end
45
+
46
+ def merge!(group)
47
+ raise "Can only merge with a Group" unless group.kind_of?(Group)
48
+ @defines += group.defines
49
+ @enums += group.enums
50
+
51
+ # TODO: do we need to merge classes and members ? I don't think so (they should be in namespace).
52
+ end
53
+
54
+ def ignore(list)
55
+ list = [list].flatten
56
+ @ignores += list
57
+ self.classes.reject! {|k| list.include?(k.name) }
58
+ @ignores.uniq!
59
+ @gen_members = nil
60
+ end
61
+
62
+ def full_type
63
+ @parent ? "#{@parent.full_type}::#{name}" : name
64
+ end
65
+
66
+ def lib_name
67
+ prefix ? "#{prefix}_#{name}" : name
68
+ end
69
+
70
+ def id_name(name = self.name)
71
+ prefix ? "#{prefix}.#{name}" : name
72
+ end
73
+
74
+ def header
75
+ @header ||= (@xml/'location').first.attributes['file'].split('/').last
76
+ end
77
+
78
+ def [](name)
79
+ get_member(name.to_s) || klass(name.to_s)
80
+ end
81
+
82
+ def function(name)
83
+ member = get_member(name.to_s)
84
+ member.kind_of?(Function) ? member : nil
85
+ end
86
+
87
+ def klass(name)
88
+ get_class(name.to_s, @classes_hash) || get_alias(name.to_s)
89
+ end
90
+
91
+ def template_class(name)
92
+ get_class(name.to_s, @t_classes_hash)
93
+ end
94
+
95
+ def classes
96
+ @classes ||= begin
97
+ list = []
98
+ @classes_hash.each do |name, member|
99
+ list << get_class(name, @classes_hash)
100
+ end
101
+ list.compact!
102
+ list.sort
103
+ end
104
+ end
105
+
106
+ def members
107
+ if self.generator
108
+ @gen_members ||= self.generator.members_list(super, @ignores)
109
+ else
110
+ super
111
+ end
112
+ end
113
+
114
+ def has_constants?
115
+ has_enums? || has_defines?
116
+ end
117
+
118
+ def has_enums?
119
+ !@enums.empty?
120
+ end
121
+
122
+ def has_defines?
123
+ !@defines.empty?
124
+ end
125
+
126
+ def register_alias(name, klass)
127
+ @class_alias[name] = klass
128
+ end
129
+
130
+ private
131
+ def parse_xml
132
+ parse_enums
133
+ parse_members
134
+ parse_classes
135
+ end
136
+
137
+ def parse_enums
138
+ @enums = (@xml/"enumvalue/name").map{|e| e.innerHTML}
139
+ end
140
+
141
+ # We do not run this by default but use groups to make sure we do
142
+ # not cluter namespace
143
+ def parse_defines
144
+ @defines = (@xml/"memberdef[@kind=define]").map do |e|
145
+ if (e/'param').first
146
+ nil
147
+ else
148
+ (e/'name').innerHTML
149
+ end
150
+ end.compact
151
+ end
152
+
153
+ def parse_classes
154
+ @classes_hash = {}
155
+ @t_classes_hash = {}
156
+ @classes_by_ref = {}
157
+ (@xml/'innerclass').each do |klass|
158
+ name = klass.innerHTML
159
+ Dub.logger.info "Parsing #{name}"
160
+ if name =~ /^#{@name}::(.+)$/
161
+ name = $1
162
+ end
163
+ filename = klass.attributes['refid']
164
+ filepath = File.join(@current_dir, "#{filename}.xml")
165
+ if File.exist?(filepath)
166
+ class_xml = (Hpricot::XML(File.read(filepath))/'compounddef').first
167
+ if (class_xml/'/templateparamlist/param').innerHTML != ''
168
+ @t_classes_hash[name] = class_xml
169
+ else
170
+ @classes_hash[name] = class_xml
171
+ end
172
+ @classes_by_ref[class_xml[:id]] = class_xml
173
+ else
174
+ Dub.logger.warn "Could not open #{filepath}"
175
+ nil
176
+ end
177
+ end
178
+ parse_template_class_typedefs
179
+ end
180
+
181
+ def parse_template_class_typedefs
182
+ (@xml/'memberdef[@kind=typedef]').each do |typedef_xml|
183
+ # <type><ref refid="classdoxy_1_1_t_mat" kindref="compound">TMat</ref>&lt; float &gt;</type>
184
+ if id = (typedef_xml/'/type/ref').first
185
+ id = id[:refid]
186
+ end
187
+
188
+ new_name = (typedef_xml/'name').innerHTML
189
+
190
+ if ref_class = @classes_by_ref[id]
191
+ if (typedef_xml/'/type').innerHTML =~ /&gt;$/
192
+
193
+ # nested template types, too hard for us, ignore
194
+ next if (typedef_xml/'/type').innerHTML =~ /&gt;\s+&gt;/
195
+
196
+ # template typedef
197
+ old_name = (ref_class/'/compoundname').first.innerHTML.gsub(/^.*::/,'')
198
+
199
+ # replace class name
200
+ class_def = ref_class.to_s.gsub(/#{old_name}&lt;.*?&gt;::/,"#{new_name}::")
201
+ class_def = class_def.gsub(/#{old_name}/, new_name)
202
+
203
+ # replace template types
204
+ # get template parameters
205
+ ttypes = (ref_class/'/templateparamlist/param').map do |param|
206
+ if type = (param/'declname').first
207
+ type.innerHTML
208
+ else
209
+ (param/'type').innerHTML.gsub(/^\s*(typename|class)\s+/,'')
210
+ end
211
+ end
212
+
213
+ types_map = {}
214
+ instanciations_params = []
215
+ (typedef_xml/'/type').innerHTML[/&lt;\s*(.+?)\s*&gt;$/,1].split(',').map(&:strip).each_with_index do |type, i|
216
+ instanciations_params << type
217
+ types_map[ttypes[i]] = type
218
+ end
219
+
220
+ class_xml = (Hpricot::XML(class_def)/'compounddef').first
221
+
222
+ (class_xml/'*[@prot=private]').remove
223
+ (class_xml/'templateparamlist').remove
224
+ (class_xml/'').append("<originaltemplate>#{old_name}</originaltemplate>")
225
+ (ref_class/'').append("<instanciation><name>#{new_name}</name><param>#{instanciations_params.join('</param><param>')}</param></instanciation>")
226
+
227
+ types_map.each do |template_type, real_type|
228
+ (class_xml/'type').each do |t|
229
+ t.swap(t.to_s.gsub(template_type, real_type))
230
+ end
231
+ end
232
+
233
+ @classes_hash[new_name] = class_xml
234
+ else
235
+ # alias
236
+ original_name = (typedef_xml/'/type/ref').innerHTML
237
+ if class_xml = @classes_hash[original_name]
238
+ @alias_names << new_name
239
+ if (class_xml/'/aliases').first
240
+ (class_xml/'/aliases').append("<name>#{new_name}</name>")
241
+ else
242
+ (class_xml/'').append("<aliases><name>#{new_name}</name></aliases>")
243
+ end
244
+ else
245
+ Dub.logger.warn "Could not find original class #{original_name}"
246
+ end
247
+ end
248
+ else
249
+ Dub.logger.warn "Could not find reference class #{id}"
250
+ end
251
+ end
252
+ end
253
+
254
+ def get_class(name, source)
255
+ if klass = source[name]
256
+ if klass.kind_of?(Hpricot::Elem)
257
+ klass = source[name] = make_member(name, klass)
258
+ end
259
+ end
260
+ klass
261
+ end
262
+
263
+ def get_alias(name)
264
+ if klass = @class_alias[name]
265
+ return klass
266
+ elsif @classes || !@alias_names.include?(name)
267
+ # classes parsed, alias does not exist
268
+ nil
269
+ else
270
+ # we need to parse all classes so they register the alias
271
+ self.classes
272
+ @class_alias[name]
273
+ end
274
+ end
275
+ end
276
+ end # Namespace
data/lib/dub/parser.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+ require 'dub/namespace'
4
+
5
+ module Dub
6
+ class Parser
7
+ def initialize(filepath)
8
+ @current_dir = File.dirname(filepath)
9
+ @xml = Hpricot::XML(File.read(filepath))
10
+ end
11
+
12
+ def [](name)
13
+ namespaces[name.to_s] || groups[name.to_s]
14
+ end
15
+
16
+ def namespace(name)
17
+ namespaces[name.to_s]
18
+ end
19
+
20
+ def group(name)
21
+ groups[name.to_s]
22
+ end
23
+
24
+ def namespaces
25
+ @namespaces ||= begin
26
+ ns = {}
27
+ (@xml/'compounddef[@kind=namespace]').each do |namespace|
28
+ name = (namespace/"compoundname").innerHTML
29
+ ns[name] = Dub::Namespace.new(name, namespace, @current_dir)
30
+ end
31
+ ns
32
+ end
33
+ end
34
+
35
+ def groups
36
+ @groups ||= begin
37
+ groups = {}
38
+ (@xml/'compounddef[@kind=group]').each do |namespace|
39
+ name = (namespace/"compoundname").innerHTML
40
+ groups[name] = Dub::Group.new(name, namespace, @current_dir)
41
+ end
42
+ groups
43
+ end
44
+ end
45
+ end # Parser
46
+ end
@@ -0,0 +1,21 @@
1
+
2
+ static bool is_userdata(lua_State *L, int index, const char *tname) {
3
+ void *p = lua_touserdata(L, index);
4
+ if (p != NULL) { /* value is a userdata? */
5
+ if (lua_getmetatable(L, index)) { /* does it have a metatable? */
6
+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
7
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
8
+ lua_pop(L, 2); /* remove both metatables */
9
+ // type match
10
+ return true;
11
+ }
12
+ }
13
+ }
14
+ // type does not match
15
+ return false;
16
+ }
17
+
18
+ <%= @bindings %>
19
+
20
+ <%= @init_code %>
21
+
@@ -0,0 +1,3 @@
1
+ module Dub
2
+ VERSION = '0.5.0'
3
+ end
data/lib/dub.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'dub/entities_unescape'
2
+ require 'dub/parser'
3
+ require 'dub/namespace'
4
+ require 'dub/group'
5
+ require 'dub/klass'
6
+ require 'dub/function'
7
+ require 'dub/argument'
8
+ require 'logger'
9
+
10
+ module Dub
11
+ def self.logger=(logger)
12
+ @@logger = logger
13
+ end
14
+
15
+ def self.logger
16
+ @@logger ||= begin
17
+ logger = Logger.new(STDERR)
18
+ logger.level == Logger::INFO
19
+ logger
20
+ end
21
+ end
22
+
23
+ def self.parse(filename)
24
+ Dub::Parser.new(filename)
25
+ end
26
+ end