dub 0.6.6 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +26 -0
- data/README.rdoc +41 -1
- data/dub.gemspec +160 -166
- data/lib/dub/argument.rb +25 -13
- data/lib/dub/function.rb +14 -4
- data/lib/dub/group.rb +2 -6
- data/lib/dub/klass.rb +55 -19
- data/lib/dub/lua/class.cpp.erb +29 -2
- data/lib/dub/lua/class_gen.rb +33 -34
- data/lib/dub/lua/function.cpp.erb +9 -12
- data/lib/dub/lua/function_gen.rb +55 -19
- data/lib/dub/lua/lua_cpp_helper.cpp +252 -0
- data/lib/dub/lua/lua_cpp_helper.h +118 -40
- data/lib/dub/lua/namespace.cpp.erb +3 -1
- data/lib/dub/lua/namespace_gen.rb +14 -33
- data/lib/dub/member_extraction.rb +47 -11
- data/lib/dub/namespace.rb +14 -3
- data/lib/dub/opts_parser.rb +3 -3
- data/lib/dub/version.rb +2 -2
- data/test/argument_test.rb +46 -12
- data/test/fixtures/app/include/matrix.h +121 -0
- data/test/fixtures/app/vendor/lua/liblua.a +0 -0
- data/test/fixtures/app/xml/classdub_1_1_base.xml +85 -0
- data/test/fixtures/app/xml/classdub_1_1_custom_destructor.xml +67 -0
- data/test/fixtures/app/xml/classdub_1_1_deletable_out_of_lua.xml +43 -0
- data/test/fixtures/app/xml/classdub_1_1_matrix.xml +162 -21
- data/test/fixtures/app/xml/classdub_1_1_no_destructor.xml +49 -0
- data/test/fixtures/app/xml/classdub_1_1_priv_sub_base.xml +89 -0
- data/test/fixtures/app/xml/classdub_1_1_private_constr.xml +68 -0
- data/test/fixtures/app/xml/classdub_1_1_static_constr.xml +69 -0
- data/test/fixtures/app/xml/classdub_1_1_sub_base.xml +89 -0
- data/test/fixtures/app/xml/classdub_1_1_t_mat.xml +15 -15
- data/test/fixtures/app/xml/index.xml +43 -0
- data/test/fixtures/app/xml/matrix_8h.xml +263 -132
- data/test/fixtures/app/xml/namespacedub.xml +10 -3
- data/test/function_group_test.rb +20 -1
- data/test/function_test.rb +10 -0
- data/test/group_test.rb +95 -9
- data/test/klass_test.rb +134 -5
- data/test/lua_function_gen_test.rb +36 -9
- metadata +20 -23
- data/.gitignore +0 -8
@@ -49,39 +49,20 @@ module Dub
|
|
49
49
|
res.join(",\n\n")
|
50
50
|
end
|
51
51
|
|
52
|
-
def members_list(all_members
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
list
|
66
|
-
list == [] ? nil : list
|
67
|
-
end
|
68
|
-
|
69
|
-
def ignore_member?(member)
|
70
|
-
if member.name =~ /^~/ || # do not build constructor
|
71
|
-
member.name =~ /^operator/ || # no conversion operators
|
72
|
-
member.original_signature =~ />/ || # no complex types in signature
|
73
|
-
member.has_array_arguments? ||
|
74
|
-
member.vararg? ||
|
75
|
-
member.original_signature =~ /void\s+\*/ ||
|
76
|
-
member.has_class_pointer_arguments?
|
77
|
-
|
78
|
-
true # ignore
|
79
|
-
elsif return_value = member.return_value
|
80
|
-
return_value.type =~ />$/ || # no complex return types
|
81
|
-
return_value.is_native? && member.return_value.is_pointer?
|
82
|
-
else
|
83
|
-
false # ok, do not ignore
|
84
|
-
end
|
52
|
+
def members_list(all_members)
|
53
|
+
all_members
|
54
|
+
#list = (all_members || []).map do |member_or_group|
|
55
|
+
# if member_or_group.kind_of?(Array)
|
56
|
+
# members_list(member_or_group)
|
57
|
+
# elsif ignore_member?(member_or_group)
|
58
|
+
# nil
|
59
|
+
# else
|
60
|
+
# member_or_group
|
61
|
+
# end
|
62
|
+
#end
|
63
|
+
#
|
64
|
+
#list.compact!
|
65
|
+
#list == [] ? nil : list
|
85
66
|
end
|
86
67
|
end
|
87
68
|
end
|
@@ -41,10 +41,11 @@ module Dub
|
|
41
41
|
get_member(name.to_s, @members_hash)
|
42
42
|
end
|
43
43
|
|
44
|
-
def members
|
44
|
+
def members(ignore_list = [])
|
45
45
|
@members ||= begin
|
46
46
|
list = []
|
47
47
|
@members_hash.each do |name, member|
|
48
|
+
next if ignore_list.include?(name)
|
48
49
|
list << get_member(name)
|
49
50
|
end
|
50
51
|
list.compact!
|
@@ -61,12 +62,23 @@ module Dub
|
|
61
62
|
if member_or_group = source[name]
|
62
63
|
if member_or_group.kind_of?(Array)
|
63
64
|
if member_or_group.first.kind_of?(Hpricot::Elem)
|
64
|
-
list =
|
65
|
-
member_or_group.
|
66
|
-
list << make_member(name, m
|
65
|
+
list = []
|
66
|
+
member_or_group.each do |m|
|
67
|
+
list << make_member(name, m)
|
68
|
+
end
|
69
|
+
list.compact!
|
70
|
+
if list == []
|
71
|
+
member_or_group = nil
|
72
|
+
elsif list.size == 1
|
73
|
+
member_or_group = list.first
|
74
|
+
else
|
75
|
+
member_or_group = Dub::FunctionGroup.new(self)
|
76
|
+
# set overloaded_index
|
77
|
+
list.each_with_index do |m, i|
|
78
|
+
m.overloaded_index = i + 1
|
79
|
+
member_or_group << m
|
80
|
+
end
|
67
81
|
end
|
68
|
-
member_or_group = list.compact
|
69
|
-
member_or_group = nil if member_or_group == []
|
70
82
|
end
|
71
83
|
elsif member_or_group.kind_of?(Hpricot::Elem)
|
72
84
|
source[name] = member_or_group = make_member(name, member_or_group)
|
@@ -75,17 +87,41 @@ module Dub
|
|
75
87
|
member_or_group
|
76
88
|
end
|
77
89
|
|
78
|
-
def make_member(name, member
|
79
|
-
case member[:kind]
|
80
|
-
when 'function'
|
90
|
+
def make_member(name, member)
|
91
|
+
member = case member[:kind]
|
92
|
+
when 'function', 'slot'
|
81
93
|
Dub.logger.info "Building #{members_prefix}::#{name}"
|
82
|
-
Function.new(self, name, member, members_prefix
|
94
|
+
Function.new(self, name, member, members_prefix)
|
83
95
|
when 'class'
|
84
96
|
Dub.logger.info "Building #{members_prefix}::#{name}"
|
85
97
|
Klass.new(self, name, member, members_prefix)
|
86
98
|
else
|
87
99
|
# not supported: ignore
|
88
|
-
nil
|
100
|
+
return nil
|
101
|
+
end
|
102
|
+
|
103
|
+
ignore_member?(member) ? nil : member
|
104
|
+
end
|
105
|
+
|
106
|
+
def ignore_member?(member)
|
107
|
+
return false if member.kind_of?(Klass)
|
108
|
+
|
109
|
+
if !member.public? ||
|
110
|
+
member.name =~ /^~/ || # do not build constructor
|
111
|
+
member.name =~ /^operator/ || # no conversion operators
|
112
|
+
member.has_complex_arguments? || # no complex arguments or return values
|
113
|
+
member.has_array_arguments? ||
|
114
|
+
member.vararg? ||
|
115
|
+
member.original_signature =~ /void\s+\*/ # used to detect return value and parameters
|
116
|
+
true # ignore
|
117
|
+
elsif return_value = member.return_value
|
118
|
+
if return_value.create_type == 'const char *'
|
119
|
+
return false # do not ignore
|
120
|
+
end
|
121
|
+
return_value.type =~ />$/ || # no complex return types
|
122
|
+
(return_value.is_native? && member.return_value.is_pointer?)
|
123
|
+
else
|
124
|
+
false # ok, do not ignore
|
89
125
|
end
|
90
126
|
end
|
91
127
|
end
|
data/lib/dub/namespace.rb
CHANGED
@@ -64,7 +64,12 @@ module Dub
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def lib_name
|
67
|
-
prefix ? "#{prefix}_#{name}" : name
|
67
|
+
@lib_name || (prefix ? "#{prefix}_#{name}" : name)
|
68
|
+
end
|
69
|
+
|
70
|
+
# FIXME: test
|
71
|
+
def lib_name=(name)
|
72
|
+
@lib_name = name
|
68
73
|
end
|
69
74
|
|
70
75
|
def id_name(name = self.name)
|
@@ -104,10 +109,11 @@ module Dub
|
|
104
109
|
end
|
105
110
|
|
106
111
|
def members
|
112
|
+
list = super(@ignores)
|
107
113
|
if self.generator
|
108
|
-
@gen_members ||= self.generator.members_list(
|
114
|
+
@gen_members ||= self.generator.members_list(list)
|
109
115
|
else
|
110
|
-
|
116
|
+
list
|
111
117
|
end
|
112
118
|
end
|
113
119
|
|
@@ -115,6 +121,11 @@ module Dub
|
|
115
121
|
has_enums? || has_defines?
|
116
122
|
end
|
117
123
|
|
124
|
+
# FIXME: test
|
125
|
+
def has_functions?
|
126
|
+
members && members != []
|
127
|
+
end
|
128
|
+
|
118
129
|
def has_enums?
|
119
130
|
!@enums.empty?
|
120
131
|
end
|
data/lib/dub/opts_parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Dub
|
2
2
|
module OptsParser
|
3
|
-
|
3
|
+
ENTRY_REGEXP = %r{^\s*([^:]+):\s*('[^']*'|"[^"]*")\s*,?\s*}m
|
4
4
|
def self.extract_hash(xml)
|
5
5
|
(xml/'simplesect').each do |x|
|
6
6
|
if (x/'title').inner_html == 'Bindings info:'
|
@@ -17,8 +17,8 @@ module Dub
|
|
17
17
|
|
18
18
|
def self.parse(src)
|
19
19
|
res = {}
|
20
|
-
while !src.empty?
|
21
|
-
src = src.sub(
|
20
|
+
while !src.empty? && src =~ ENTRY_REGEXP
|
21
|
+
src = src.sub(ENTRY_REGEXP) do
|
22
22
|
res[$1.to_sym] = $2[1..-2]
|
23
23
|
''
|
24
24
|
end
|
data/lib/dub/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Dub
|
2
|
-
VERSION = '0.
|
3
|
-
end
|
2
|
+
VERSION = '0.7.0'
|
3
|
+
end
|
data/test/argument_test.rb
CHANGED
@@ -160,45 +160,49 @@ class ArgumentTest < Test::Unit::TestCase
|
|
160
160
|
end
|
161
161
|
|
162
162
|
context 'A bool argument' do
|
163
|
-
|
163
|
+
subject do
|
164
164
|
# namespacecv_xml = Dub.parse(fixture('namespacecv.xml'))
|
165
|
-
|
165
|
+
namespacedub_xml[:dub][:Matrix][:do_something].arguments[1]
|
166
|
+
end
|
167
|
+
|
168
|
+
should 'belong to the :boolean group' do
|
169
|
+
assert_equal :boolean, Dub::Argument.type_group(MockArgument.new('bool'))
|
166
170
|
end
|
167
171
|
|
168
172
|
should 'return type with type' do
|
169
|
-
assert_equal 'bool',
|
173
|
+
assert_equal 'bool', subject.type
|
170
174
|
end
|
171
175
|
|
172
176
|
should 'return name with name' do
|
173
|
-
assert_equal 'fast',
|
177
|
+
assert_equal 'fast', subject.name
|
174
178
|
end
|
175
179
|
|
176
180
|
should 'know if argument is const' do
|
177
|
-
assert
|
181
|
+
assert !subject.is_const?
|
178
182
|
end
|
179
183
|
|
180
184
|
should 'know if argument is passed by ref' do
|
181
|
-
assert
|
185
|
+
assert !subject.is_ref?
|
182
186
|
end
|
183
187
|
|
184
188
|
should 'know that it is a pointer' do
|
185
|
-
assert
|
189
|
+
assert !subject.is_pointer?
|
186
190
|
end
|
187
191
|
|
188
192
|
should 'know if argument type is a native type' do
|
189
|
-
assert
|
193
|
+
assert subject.is_native?
|
190
194
|
end
|
191
195
|
|
192
196
|
should 'return bool on create_type' do
|
193
|
-
assert_equal 'bool ',
|
197
|
+
assert_equal 'bool ', subject.create_type
|
194
198
|
end
|
195
199
|
|
196
200
|
should 'return signature' do
|
197
|
-
assert_equal 'bool',
|
201
|
+
assert_equal 'bool', subject.signature
|
198
202
|
end
|
199
203
|
|
200
204
|
should 'return default value if it has one' do
|
201
|
-
assert_equal 'false',
|
205
|
+
assert_equal 'false', subject.default
|
202
206
|
end
|
203
207
|
end
|
204
208
|
|
@@ -229,7 +233,7 @@ class ArgumentTest < Test::Unit::TestCase
|
|
229
233
|
end
|
230
234
|
|
231
235
|
should 'not nest own namespace in type' do
|
232
|
-
assert_match %r{luaL_checkudata\(L,\s
|
236
|
+
assert_match %r{luaL_checkudata\(L,\s*\d,\s*\"std\.string\"}, @function.to_s
|
233
237
|
end
|
234
238
|
end
|
235
239
|
end
|
@@ -489,6 +493,36 @@ class ArgumentTest < Test::Unit::TestCase
|
|
489
493
|
end
|
490
494
|
end
|
491
495
|
|
496
|
+
context 'A pointer to a const char' do
|
497
|
+
setup do
|
498
|
+
@argument = namespacedub_xml[:dub][:Matrix][:name].return_value
|
499
|
+
end
|
500
|
+
|
501
|
+
should 'belong to the string group' do
|
502
|
+
assert_equal :string, Dub::Argument.type_group(MockArgument.new('char', 'char', true))
|
503
|
+
end
|
504
|
+
|
505
|
+
should 'know if argument is const' do
|
506
|
+
assert @argument.is_const?
|
507
|
+
end
|
508
|
+
|
509
|
+
should 'know if argument is passed by ref' do
|
510
|
+
assert !@argument.is_ref?
|
511
|
+
end
|
512
|
+
|
513
|
+
should 'know that it is a pointer' do
|
514
|
+
assert @argument.is_pointer?
|
515
|
+
end
|
516
|
+
|
517
|
+
should 'return the type without star' do
|
518
|
+
assert_equal 'char', @argument.type
|
519
|
+
end
|
520
|
+
|
521
|
+
should 'create a native type' do
|
522
|
+
assert_equal 'const char *', @argument.create_type
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
492
526
|
context 'In a class defined from a template' do
|
493
527
|
setup do
|
494
528
|
@class = namespacecv_xml[:cv][:Scalar]
|
@@ -6,6 +6,7 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
/** @file */
|
9
|
+
typedef int LuaStackSize;
|
9
10
|
|
10
11
|
namespace dub {
|
11
12
|
|
@@ -13,8 +14,12 @@ namespace dub {
|
|
13
14
|
*
|
14
15
|
* @dub var_from_dub:'dummy value'
|
15
16
|
* other_from_dub: "some other value"
|
17
|
+
* ignore: 'bad_method'
|
16
18
|
*/
|
17
19
|
class Matrix {
|
20
|
+
|
21
|
+
Q_PROPERTY(size_t foo_prop READ size)
|
22
|
+
Q_PROPERTY(size_t size READ size WRITE setSize)
|
18
23
|
public:
|
19
24
|
Matrix() : data_(NULL), rows_(0), cols_(0) {}
|
20
25
|
|
@@ -58,6 +63,14 @@ public:
|
|
58
63
|
|
59
64
|
}
|
60
65
|
|
66
|
+
void do_something(int i, const char *baz) {
|
67
|
+
// overloaded member method
|
68
|
+
}
|
69
|
+
|
70
|
+
void bad_method(int i) {
|
71
|
+
// method should not exist in bindings
|
72
|
+
}
|
73
|
+
|
61
74
|
void use_other_lib(const std::string &name) {
|
62
75
|
// dummy
|
63
76
|
}
|
@@ -66,10 +79,24 @@ public:
|
|
66
79
|
// dummy
|
67
80
|
}
|
68
81
|
|
82
|
+
bool true() {
|
83
|
+
// dummy
|
84
|
+
return true;
|
85
|
+
}
|
86
|
+
|
87
|
+
const char *name() {
|
88
|
+
// should make method return string
|
89
|
+
}
|
90
|
+
|
69
91
|
int *lua_thing(int a, lua_State *L, int b) {
|
70
92
|
// dummy
|
71
93
|
}
|
72
94
|
|
95
|
+
LuaStackSize work_with_lua(int a, int b) {
|
96
|
+
// method that directly pushes lua values on the stack
|
97
|
+
return 2;
|
98
|
+
}
|
99
|
+
|
73
100
|
/** Named constructor.
|
74
101
|
*/
|
75
102
|
static Matrix *MakeMatrix(int rows, int cols) {
|
@@ -77,6 +104,9 @@ public:
|
|
77
104
|
}
|
78
105
|
|
79
106
|
private:
|
107
|
+
Matrix(int x) {
|
108
|
+
// private constructor
|
109
|
+
}
|
80
110
|
|
81
111
|
int private_method() {
|
82
112
|
// should not be implemented
|
@@ -96,6 +126,97 @@ protected:
|
|
96
126
|
};
|
97
127
|
|
98
128
|
|
129
|
+
/** Test that private constructors are not used.
|
130
|
+
*/
|
131
|
+
class PrivateConstr {
|
132
|
+
public:
|
133
|
+
|
134
|
+
PrivateConstr(int x) {}
|
135
|
+
|
136
|
+
~PrivateConstr() {}
|
137
|
+
|
138
|
+
private:
|
139
|
+
// should not be used to build a FunctionGroup
|
140
|
+
PrivateConstr(const char *name) {}
|
141
|
+
};
|
142
|
+
|
143
|
+
/** Test that custom destructors are used.
|
144
|
+
* @dub destructor: 'dub_destroy'
|
145
|
+
*/
|
146
|
+
class CustomDestructor : public DeletableOutOfLua
|
147
|
+
{
|
148
|
+
public:
|
149
|
+
|
150
|
+
CustomDestructor(int x) {}
|
151
|
+
|
152
|
+
~CustomDestructor() {}
|
153
|
+
|
154
|
+
void do_this(int x) {
|
155
|
+
|
156
|
+
}
|
157
|
+
};
|
158
|
+
|
159
|
+
/** Test that no destructor option is used.
|
160
|
+
*
|
161
|
+
* @dub destructor: ''
|
162
|
+
*/
|
163
|
+
class NoDestructor {
|
164
|
+
public:
|
165
|
+
|
166
|
+
NoDestructor(int x) {}
|
167
|
+
|
168
|
+
~NoDestructor() {}
|
169
|
+
};
|
170
|
+
|
171
|
+
/** Test that we can use a static constructor.
|
172
|
+
* @dub constructor: 'MakeStaticConstr'
|
173
|
+
*/
|
174
|
+
class StaticConstr {
|
175
|
+
public:
|
176
|
+
|
177
|
+
StaticConstr(int x) {}
|
178
|
+
|
179
|
+
~StaticConstr() {}
|
180
|
+
|
181
|
+
// We usually want to push the userdata ourself in
|
182
|
+
// such cases.
|
183
|
+
static LuaStackSize MakeStaticConstr(lua_State *L) {
|
184
|
+
return 0; // fake error (nil return)
|
185
|
+
}
|
186
|
+
};
|
187
|
+
|
188
|
+
// class inheritence tests
|
189
|
+
class Base {
|
190
|
+
public:
|
191
|
+
Base() {}
|
192
|
+
~Base() {}
|
193
|
+
|
194
|
+
const char *method_in_base(int x, float y) {
|
195
|
+
return "nothing";
|
196
|
+
}
|
197
|
+
};
|
198
|
+
|
199
|
+
// class inheritence tests
|
200
|
+
class SubBase : public Base {
|
201
|
+
public:
|
202
|
+
SubBase() {}
|
203
|
+
~SubBase() {}
|
204
|
+
|
205
|
+
void method_in_sub(float y) {
|
206
|
+
return "nothing";
|
207
|
+
}
|
208
|
+
};
|
209
|
+
|
210
|
+
// class inheritence tests
|
211
|
+
class PrivSubBase : private Base {
|
212
|
+
public:
|
213
|
+
SubBase() {}
|
214
|
+
~SubBase() {}
|
215
|
+
|
216
|
+
void method_in_sub(float y) {
|
217
|
+
return "nothing";
|
218
|
+
}
|
219
|
+
};
|
99
220
|
template<class T>
|
100
221
|
class TMat {
|
101
222
|
public:
|