doxyparser 1.2
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.
- checksums.yaml +7 -0
- data/MIT_LICENSE +19 -0
- data/README.md +271 -0
- data/lib/doxyparser.rb +75 -0
- data/lib/nodes/class.rb +13 -0
- data/lib/nodes/compound.rb +42 -0
- data/lib/nodes/enum.rb +20 -0
- data/lib/nodes/friend.rb +20 -0
- data/lib/nodes/function.rb +54 -0
- data/lib/nodes/group.rb +6 -0
- data/lib/nodes/hfile.rb +73 -0
- data/lib/nodes/member.rb +61 -0
- data/lib/nodes/namespace.rb +66 -0
- data/lib/nodes/node.rb +63 -0
- data/lib/nodes/param.rb +34 -0
- data/lib/nodes/struct.rb +89 -0
- data/lib/nodes/type.rb +29 -0
- data/lib/nodes/typedef.rb +6 -0
- data/lib/nodes/variable.rb +6 -0
- data/lib/util.rb +69 -0
- data/spec/class_spec.rb +166 -0
- data/spec/custom_spec_helper.rb +21 -0
- data/spec/doxyparser_spec.rb +23 -0
- data/spec/enum_spec.rb +18 -0
- data/spec/file_spec.rb +108 -0
- data/spec/method_spec.rb +86 -0
- data/spec/namespace_spec.rb +165 -0
- data/spec/type_spec.rb +34 -0
- metadata +83 -0
data/lib/nodes/type.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Doxyparser
|
2
|
+
|
3
|
+
class Type < Node
|
4
|
+
|
5
|
+
def nested_local_types
|
6
|
+
refs = @node.xpath("ref")
|
7
|
+
return [] if refs.nil? || refs.empty?
|
8
|
+
refs.map { |r| Type.new(node: r, dir: @dir) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def nested_typenames
|
12
|
+
splitted = @name.split(%r{[<,>]}).map{|s| s.strip}.reject!{|s| s.nil? || !(s =~ /^\D[\w:]*\w$/)}
|
13
|
+
end
|
14
|
+
|
15
|
+
def template?
|
16
|
+
@name.include? '<'
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def init_attributes
|
22
|
+
@basename = @name
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_name
|
26
|
+
@node.content
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/util.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
module Doxyparser
|
2
|
+
|
3
|
+
module Util
|
4
|
+
|
5
|
+
def self.home_dir
|
6
|
+
File.expand_path('..', File.dirname(__FILE__))
|
7
|
+
end
|
8
|
+
|
9
|
+
def del_spaces n
|
10
|
+
n.gsub(/\s+/, "")
|
11
|
+
end
|
12
|
+
|
13
|
+
def del_prefix n
|
14
|
+
n.gsub(%r{.*[:/]}, "")
|
15
|
+
end
|
16
|
+
|
17
|
+
def escape_file_name filename
|
18
|
+
if filename =~ %r{[\./]}
|
19
|
+
return filename.gsub('.', '_8').gsub('/', '_2')
|
20
|
+
else
|
21
|
+
return filename.gsub('_8', '.').gsub('_2', '/')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def escape_class_name filename
|
26
|
+
if filename.include? '::'
|
27
|
+
return filename.gsub('::','_1_1')
|
28
|
+
else
|
29
|
+
return filename.gsub('_1_1','::')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.read_file file_name
|
34
|
+
file = File.open(file_name, "r")
|
35
|
+
data = file.read
|
36
|
+
file.close
|
37
|
+
return data
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.write_file file_name, data
|
41
|
+
file = File.open(file_name, "w")
|
42
|
+
count = file.write(data)
|
43
|
+
file.close
|
44
|
+
return count
|
45
|
+
end
|
46
|
+
|
47
|
+
def do_filter filter, lst, clazz
|
48
|
+
if filter
|
49
|
+
filtered_lst = []
|
50
|
+
filter.each { |val|
|
51
|
+
found = lst.select { |node| match(val, yield(node)) }
|
52
|
+
raise "The object: #{val} #{clazz} could not be found while parsing" if found.nil? || found.empty?
|
53
|
+
filtered_lst.push(*found)
|
54
|
+
}
|
55
|
+
else
|
56
|
+
filtered_lst=lst
|
57
|
+
end
|
58
|
+
filtered_lst.map { |node| clazz.new(parent: self, node: node) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def match val, aux_name
|
62
|
+
if val.is_a? Regexp
|
63
|
+
return aux_name =~ val
|
64
|
+
else
|
65
|
+
return aux_name == val
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/spec/class_spec.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'doxyparser'
|
4
|
+
|
5
|
+
require_relative 'custom_spec_helper'
|
6
|
+
|
7
|
+
describe "Doxyparser::Class" do
|
8
|
+
|
9
|
+
context "Basic - Creation" do
|
10
|
+
|
11
|
+
it "should create consistently classes from diferent namespaces" do
|
12
|
+
|
13
|
+
klass_syms = { templateClass: "MyNamespace::TemplateClass",
|
14
|
+
myClass: "MyNamespace::MyClass",
|
15
|
+
myClass_inner: "MyNamespace::MyInnerNamespace::MyMostInnerNamespace::MyClass",
|
16
|
+
innerClass: "MyNamespace::MyClass::InnerClass"}
|
17
|
+
|
18
|
+
struct_syms = { outerStruct: "MyNamespace::OuterStruct",
|
19
|
+
innerStruct: "MyNamespace::MyClass::InnerStruct"}
|
20
|
+
|
21
|
+
klasses = {}
|
22
|
+
|
23
|
+
klass_syms.each_key {|k|
|
24
|
+
klasses[k] = Doxyparser::parse_class(klass_syms[k], xml_dir)
|
25
|
+
}
|
26
|
+
|
27
|
+
struct_syms.each_key {|k|
|
28
|
+
klasses[k] = Doxyparser::parse_struct(struct_syms[k], xml_dir)
|
29
|
+
}
|
30
|
+
|
31
|
+
klasses.each {|k, v|
|
32
|
+
v.file.basename.should eql "test1.h"
|
33
|
+
v.file.xml_path.should eql "#{xml_dir}/test1_8h.xml"
|
34
|
+
v.name.should eql (klass_syms[k] || struct_syms[k])
|
35
|
+
}
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should correctly create template classes" do
|
40
|
+
template_class = Doxyparser::parse_class('MyNamespace::TemplateClass', xml_dir)
|
41
|
+
params = template_class.template_params
|
42
|
+
params.size.should eql 3
|
43
|
+
params.each {|param|
|
44
|
+
param.class.should eql Doxyparser::Param
|
45
|
+
param.type.class.should eql Doxyparser::Type
|
46
|
+
}
|
47
|
+
params[0].declname.should eql 'TYPE'
|
48
|
+
params[1].declname.should eql 'TYPE2'
|
49
|
+
params[2].declname.should eql 'entero'
|
50
|
+
params[2].value.should eql '5'
|
51
|
+
params[0].type.basename.should eql 'typename'
|
52
|
+
params[1].type.basename.should eql 'class'
|
53
|
+
params[2].type.basename.should eql 'int'
|
54
|
+
params[0].type.basename.should eql 'typename'
|
55
|
+
params[1].type.basename.should eql 'class'
|
56
|
+
params[2].type.basename.should eql 'int'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should correctly create classes in subdirectories" do
|
60
|
+
clazz=Doxyparser::parse_class("MyNamespace::SubDirClass", xml_dir)
|
61
|
+
file = clazz.file
|
62
|
+
file.name.should eql 'subdir/test1.h'
|
63
|
+
file.basename.should eql 'test1.h'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "Basic - Members" do
|
68
|
+
|
69
|
+
before(:all) do
|
70
|
+
@class=Doxyparser::parse_class("MyNamespace::MyClass", xml_dir)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should correctly create file " do
|
74
|
+
file = @class.file
|
75
|
+
file.name.should eql 'test1.h'
|
76
|
+
file.basename.should eql 'test1.h'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should correctly create inner classes and structs" do
|
80
|
+
innerstruct = @class.innerstructs
|
81
|
+
innerclass = @class.innerclasses
|
82
|
+
innerstruct.size.should eql 1
|
83
|
+
innerclass.size.should eql 1
|
84
|
+
innerstruct= innerstruct[0]
|
85
|
+
innerclass= innerclass[0]
|
86
|
+
|
87
|
+
innerstruct.class.should eql Doxyparser::Struct
|
88
|
+
innerclass.class.should eql Doxyparser::Class
|
89
|
+
innerclass.parent.should eql @class
|
90
|
+
innerclass.xml_path.should eql xml_dir+"/#{innerclass.refid}.xml"
|
91
|
+
innerclass.name.should be_start_with("#{@class.name}::")
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should correctly create methods " do
|
95
|
+
expected_methods=['MyClass', 'virtualMethod', 'method', 'operator-', '~MyClass']
|
96
|
+
methods = @class.methods
|
97
|
+
compare_members methods, expected_methods
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should correctly create static methods " do
|
101
|
+
expected_methods=['publicStaticMethod', 'getStaticProp', 'setStaticProp']
|
102
|
+
methods = @class.methods(:public, :static)
|
103
|
+
compare_members methods, expected_methods
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should correctly create private methods " do
|
107
|
+
expected_methods=['privateMethod1', 'privateMethod2']
|
108
|
+
methods = @class.methods(:private)
|
109
|
+
compare_members methods, expected_methods
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should correctly create private static methods " do
|
113
|
+
expected_methods=['privateStaticMethod']
|
114
|
+
methods = @class.methods(:private, :static)
|
115
|
+
compare_members methods, expected_methods
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should correctly create protected methods " do
|
119
|
+
expected_methods=['protectedMethod1', 'protectedMethod2']
|
120
|
+
methods = @class.methods(:protected)
|
121
|
+
compare_members methods, expected_methods
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should correctly create static attributes " do
|
125
|
+
expected_attributes=['publicStaticField1']
|
126
|
+
attributes = @class.attributes(:public, :static)
|
127
|
+
compare_members attributes, expected_attributes, Doxyparser::Variable
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should correctly create private attributes " do
|
131
|
+
expected_attributes=['privateField1', 'privateField2']
|
132
|
+
attributes = @class.attributes(:private)
|
133
|
+
compare_members attributes, expected_attributes, Doxyparser::Variable
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should correctly create public enums " do
|
137
|
+
expected_enums=['_Enum', 'InnerEnum']
|
138
|
+
enums = @class.innerenums
|
139
|
+
compare_members enums, expected_enums, Doxyparser::Enum
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should correctly create public typedefs " do
|
143
|
+
expected_typedefs=['VectorMapShortVectorInt', 'MapShortVectorInt']
|
144
|
+
typedefs = @class.typedefs :public
|
145
|
+
compare_members typedefs, expected_typedefs, Doxyparser::Typedef
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should correctly create private typedefs " do
|
149
|
+
expected_typedefs=['privateTypedef']
|
150
|
+
typedefs = @class.typedefs :private
|
151
|
+
compare_members typedefs, expected_typedefs, Doxyparser::Typedef
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should correctly create friends" do
|
155
|
+
expected_friends=['operator*', 'MyNamespace::friendMethod', 'OuterStruct']
|
156
|
+
friends = @class.friends
|
157
|
+
compare_members friends, expected_friends, Doxyparser::Friend
|
158
|
+
friend_classes = friends.select{|f| f.is_class?}
|
159
|
+
friend_classes.size.should eql 1
|
160
|
+
'OuterStruct'.should eql friend_classes[0].basename
|
161
|
+
qualified_friends = friends.select{|f| f.is_qualified?}
|
162
|
+
qualified_friends.size.should eql 1
|
163
|
+
'MyNamespace::friendMethod'.should eql qualified_friends[0].basename
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
def home_dir
|
2
|
+
File.expand_path('..', File.dirname(__FILE__))
|
3
|
+
end
|
4
|
+
|
5
|
+
def xml_dir
|
6
|
+
home_dir + '/spec/xml'
|
7
|
+
end
|
8
|
+
|
9
|
+
def compare_members members, expected_members, clazz = Doxyparser::Function
|
10
|
+
basename_members = members.map{|m| m.basename}.uniq.sort
|
11
|
+
expected_members.sort!
|
12
|
+
|
13
|
+
basename_members.should eql expected_members
|
14
|
+
|
15
|
+
members.each{ |m|
|
16
|
+
m.class.should eql clazz
|
17
|
+
m.name.should be_start_with("#{@class.name}::")
|
18
|
+
m.parent.should eql @class
|
19
|
+
m.location.should match %r{#{home_dir}/spec/headers/test1.h:\d+}
|
20
|
+
}
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'doxyparser'
|
4
|
+
|
5
|
+
require_relative 'custom_spec_helper'
|
6
|
+
|
7
|
+
describe "Doxyparser" do
|
8
|
+
|
9
|
+
it "should not burn with api calls" do
|
10
|
+
clazz=Doxyparser::parse_class("MyNamespace::MyClass", xml_dir)
|
11
|
+
namespace=Doxyparser::parse_namespace("MyNamespace", xml_dir)
|
12
|
+
struct=Doxyparser::parse_struct("MyNamespace::MyClass::InnerStruct", xml_dir)
|
13
|
+
hfile=Doxyparser::parse_file("test.h", xml_dir)
|
14
|
+
output = Doxyparser::gen_xml_docs(home_dir + '/spec/headers', home_dir + '/spec/test_gen', true, ['usr/local/include', 'usr/gato'])
|
15
|
+
output.should_not be_empty
|
16
|
+
FileUtils.rm_r(home_dir + '/spec/test_gen')
|
17
|
+
clazz.name.should_not be_empty
|
18
|
+
namespace.name.should_not be_empty
|
19
|
+
struct.name.should_not be_empty
|
20
|
+
hfile.name.should_not be_empty
|
21
|
+
hfile.basename.should_not be_empty
|
22
|
+
end
|
23
|
+
end
|
data/spec/enum_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'doxyparser'
|
4
|
+
|
5
|
+
require_relative 'custom_spec_helper'
|
6
|
+
|
7
|
+
describe "Doxyparser::Enum" do
|
8
|
+
|
9
|
+
it "should create consistently enums" do
|
10
|
+
|
11
|
+
clazz = Doxyparser::parse_class('MyNamespace::MyClass', xml_dir)
|
12
|
+
enum = clazz.innerenums(:public, ['_Enum'])
|
13
|
+
enum.size.should eql 1
|
14
|
+
enum[0].values.should eql ['value1', 'value2','value3']
|
15
|
+
enum = clazz.innerenums(:public, ['InnerEnum'])
|
16
|
+
enum[0].values.should eql ['A', 'B','C']
|
17
|
+
end
|
18
|
+
end
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'doxyparser'
|
4
|
+
|
5
|
+
require_relative 'custom_spec_helper'
|
6
|
+
|
7
|
+
describe "Doxyparser::HFile" do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
@file = Doxyparser::parse_file('test1.h', xml_dir)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should correctly create files in subdirectories" do
|
14
|
+
subdir_file = Doxyparser::parse_file('subdir/test1.h', xml_dir)
|
15
|
+
subdir_file.name.should eql 'subdir/test1.h'
|
16
|
+
subdir_file.basename.should eql 'test1.h'
|
17
|
+
subdir_file.xml_path.should eql xml_dir+'/subdir_2test1_8h.xml'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be created correctly" do
|
21
|
+
@file.name.should eql 'test1.h'
|
22
|
+
@file.basename.should eql 'test1.h'
|
23
|
+
@file.xml_path.should eql xml_dir+'/test1_8h.xml'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should correctly generate includes and included_by listing" do
|
27
|
+
expected_included= ['stdlib.h', 'vector', 'list', 'map', 'iostream', 'test3.h', 'subdir/test1.h'].sort
|
28
|
+
expected_including= ['test3.h', 'test2.h', 'test4.h', 'subdir/test2.h'].sort
|
29
|
+
@file.list_included.sort.should eql expected_included
|
30
|
+
@file.list_including.sort.should eql expected_including
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should correctly generate includes and included_by files" do
|
34
|
+
expected_included= ['test3.h', 'subdir/test1.h'].sort
|
35
|
+
expected_including= ['test3.h', 'test2.h', 'test4.h', 'subdir/test2.h'].sort
|
36
|
+
@file.files_included.map{|f| f.name}.sort.should eql expected_included
|
37
|
+
@file.files_including.map{|f| f.name}.sort.should eql expected_including
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should create the right classes and structs" do
|
41
|
+
expected_classes=['noNsClass', "MyNamespace::MyInnerNamespace::MyMostInnerNamespace::MyClass", "MyNamespace::TemplateClass", "MyNamespace::MyClass", "MyNamespace::MyClass::InnerClass"]
|
42
|
+
expected_structs=["noNsStruct", "MyNamespace::OuterStruct", "MyNamespace::MyClass::InnerStruct"]
|
43
|
+
|
44
|
+
file_classes = @file.classes
|
45
|
+
file_structs = @file.structs
|
46
|
+
file_classes.size.should eql expected_classes.size
|
47
|
+
file_structs.size.should eql expected_structs.size
|
48
|
+
|
49
|
+
file_all = file_classes + file_structs
|
50
|
+
file_all.uniq.should eql file_all# No element should be repeated
|
51
|
+
|
52
|
+
file_classes.each{|c|
|
53
|
+
c.class.should eql Doxyparser::Class
|
54
|
+
expected_classes.should include c.name
|
55
|
+
c.parent.should be_nil
|
56
|
+
c.xml_path.should be_start_with xml_dir
|
57
|
+
}
|
58
|
+
file_structs.each{|c|
|
59
|
+
c.class.should eql Doxyparser::Struct
|
60
|
+
expected_structs.should include c.name
|
61
|
+
c.parent.should be_nil
|
62
|
+
c.xml_path.should be_start_with xml_dir
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should create the right namespaces" do
|
67
|
+
expected_namespaces=['MyNamespace', "MyNamespace::MyInnerNamespace", "MyNamespace::MyInnerNamespace::MyMostInnerNamespace", "std"]
|
68
|
+
file_namespaces = @file.namespaces
|
69
|
+
file_namespaces.size.should eql expected_namespaces.size
|
70
|
+
|
71
|
+
file_namespaces.uniq.should eql file_namespaces # No element should be repeated
|
72
|
+
|
73
|
+
file_namespaces.each{|c|
|
74
|
+
c.class.should eql Doxyparser::Namespace
|
75
|
+
expected_namespaces.should include c.name
|
76
|
+
c.parent.should be_nil
|
77
|
+
c.xml_path.should be_start_with xml_dir
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create functions" do
|
82
|
+
functions = @file.functions
|
83
|
+
functions.size.should eql 1
|
84
|
+
functions[0].name.should eql 'test1.h::noNsFunction'
|
85
|
+
functions[0].basename.should eql 'noNsFunction'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should create variables" do
|
89
|
+
variables = @file.variables
|
90
|
+
variables.size.should eql 1
|
91
|
+
variables[0].name.should eql 'test1.h::noNsVariable'
|
92
|
+
variables[0].basename.should eql 'noNsVariable'
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should create enums" do
|
96
|
+
enums = @file.enums
|
97
|
+
enums.size.should eql 1
|
98
|
+
enums[0].name.should eql 'test1.h::noNsEnum'
|
99
|
+
enums[0].basename.should eql 'noNsEnum'
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should create typedefs" do
|
103
|
+
typedefs = @file.typedefs
|
104
|
+
typedefs.size.should eql 1
|
105
|
+
typedefs[0].name.should eql 'test1.h::noNsTypedef'
|
106
|
+
typedefs[0].basename.should eql 'noNsTypedef'
|
107
|
+
end
|
108
|
+
end
|