doxyparser 1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 529b48f43c4fd9b2bbc9acb11ab140d9e6150e09
|
4
|
+
data.tar.gz: df41fcf999c92693df3cf2f9dfee73f1b1b095ce
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a22858cbfdfe61b3d7248736ccbdc7f8ca22f03c415e6f30905e10ea3a820ce1dbb2db4e51e6fb0f307463422aa154eb24194bf8458fa4ac8cd7d5da6bcbc94
|
7
|
+
data.tar.gz: 8bec965f048166cc90ac92dcd2fb7beede9ea6a9e1b0e5cee343d6c1753918d9305971ca2b3c8fcc6613199d51089faedb61f7497a14047befb4958804b6cf8d
|
data/MIT_LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2013 David Fuenmayor
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,271 @@
|
|
1
|
+
# Doxyparser
|
2
|
+
|
3
|
+
Ruby Gem for parsing C++ header files.
|
4
|
+
|
5
|
+
This library is based on Nokogiri (http://nokogiri.org) and takes as input the xml files generated by Doxygen (www.doxygen.org).
|
6
|
+
|
7
|
+
Using Doxygen allows us to parse even a set of non-compilable include files. This is very useful in case you need to parse only a subset of a big library which won't normally compile because of being incomplete or needing further build configuration (e.g Makefiles, VS, SCons, etc).
|
8
|
+
|
9
|
+
By using other tools which rely on a real C/C++ processor like gccxml or swig, you would normally get lots of compilation-related errors (which is undesired because we don't want to compile anything!!). Doxyparser is, in such cases, the lean alternative.
|
10
|
+
|
11
|
+
|
12
|
+
Install
|
13
|
+
--------
|
14
|
+
|
15
|
+
```shell
|
16
|
+
gem install doxyparser
|
17
|
+
```
|
18
|
+
or add the following line to Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'doxyparser'
|
22
|
+
```
|
23
|
+
and run `bundle install` from your shell.
|
24
|
+
|
25
|
+
In order to use Doxyparser you need to first install Doxygen (www.doxygen.org) in your computer and Nokogiri (http://nokogiri.org)
|
26
|
+
|
27
|
+
Generating intermediate XML representation
|
28
|
+
------------------------------------------
|
29
|
+
|
30
|
+
Generate Doxygen documentation for a set of header files:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
Doxyparser::gen_xml_docs('/path/to/c++/files', '/desired/path/to/doxygen/docs')
|
34
|
+
```
|
35
|
+
|
36
|
+
The first argument is a directory where the target c++ files are (normally .h header files)
|
37
|
+
The second argument is a directory where the doxygen generated documentation will be created. It will contain afterwards one or two subdirectories: 'xml' and 'html' (according to the value of the gen_html flag)
|
38
|
+
|
39
|
+
There are other three optional arguments you can use. You have access to the console output too.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
output = Doxyparser::gen_xml_docs('/path/to/c++/files', '/desired/path/to/doxygen/docs', read_recursively?, ['path/to/system/include/dirs'], gen_html?)
|
43
|
+
```
|
44
|
+
|
45
|
+
If you already have the needed XMLs, you can skip this step. Keep in mind that the EXTRACT_ALL = true flag in the Doxyfile must be set in order to accurately parse the files.
|
46
|
+
|
47
|
+
Parsing intermediate XMLs
|
48
|
+
--------------------------
|
49
|
+
|
50
|
+
Doxyparser uses Nokogiri under the hood to parse and query the Doxygen generated XMLs. Therefore we need the path to the directory containing those files, as generated with the former command. For instance:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
xml_dir= '/desired/path/to/doxygen/docs/xml'
|
54
|
+
```
|
55
|
+
|
56
|
+
Doxygen generates a XML file for each namespace, class, struct and file in the given directory. Now we can parse them:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
namespace = Doxyparser::parse_namespace("MyNamespace", xml_dir) # Instance of Doxyparser::Namespace
|
60
|
+
clazz = Doxyparser::parse_class("MyNamespace::MyClass", xml_dir) # Instance of Doxyparser::Class
|
61
|
+
struct = Doxyparser::parse_struct("MyNamespace::MyClass::InnerStruct", xml_dir) # Instance of Doxyparser::Struct
|
62
|
+
hfile = Doxyparser::parse_file("test.h", xml_dir) # Instance of Doxyparser::HFile
|
63
|
+
```
|
64
|
+
|
65
|
+
Each of them will have following attributes:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
struct.name # == 'MyNamespace::MyClass::InnerStruct'
|
69
|
+
struct.basename # == 'InnerStruct'
|
70
|
+
struct.dir # == xml_dir == '/desired/path/to/doxygen/docs/xml'
|
71
|
+
struct.xml_path # == '/desired/path/to/doxygen/docs/xml/structMyNamespace_1_1MyClass_1_1InnerStruct.xml'
|
72
|
+
```
|
73
|
+
|
74
|
+
Querying Members
|
75
|
+
-----------------
|
76
|
+
|
77
|
+
Namespaces
|
78
|
+
-----------
|
79
|
+
|
80
|
+
namespace_classes = namespace.classes # List of Doxyparser::Class
|
81
|
+
namespace_structs = namespace.structs # List of Doxyparser::Struct
|
82
|
+
inner_namespaces = namespace.innernamespaces # List of Doxyparser::Namespace
|
83
|
+
namepace_enums = namespace.enums # List of Doxyparser::Enum
|
84
|
+
namespace_variables = namespace.variables # List of Doxyparser::Variable
|
85
|
+
namespace_functions = namespace.functions # List of Doxyparser::Function
|
86
|
+
namespace_typedefs = namespace.typedefs # List of Doxyparser::Typedef
|
87
|
+
|
88
|
+
...and:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
namespace_classes[0].parent == namespace # true
|
92
|
+
```
|
93
|
+
|
94
|
+
This last also applies for every other member (functions, enums, etc)
|
95
|
+
|
96
|
+
If you only want to query a subset of the namespace members, provide a list of strings or regexes as a parameter:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
expected_functions=['operator>', 'operator<=', 'intersect', 'advanceRawPointer', 'any_cast']
|
100
|
+
ns_functions = @namespace.functions(expected_functions)
|
101
|
+
```
|
102
|
+
|
103
|
+
Files
|
104
|
+
-----
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
file_classes = file.classes # List of Doxyparser::Class
|
108
|
+
file_structs = file.structs # List of Doxyparser::Struct
|
109
|
+
namepace_enums = file.enums # List of Doxyparser::Enum
|
110
|
+
file_variables = file.variables # List of Doxyparser::Variable
|
111
|
+
file_functions = file.functions # List of Doxyparser::Function
|
112
|
+
file_typedefs = file.typedefs # List of Doxyparser::Typedef
|
113
|
+
```
|
114
|
+
|
115
|
+
Information about other header files included by this:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
list_files_included = file.list_included # e.g ['cstdlib', 'list', 'map', 'subdir/test1.h']
|
119
|
+
files_included = file.files_included # List of Doxyparser::HFile (only for local header files i.e with XML representation in xml_dir)
|
120
|
+
```
|
121
|
+
|
122
|
+
Information about other header files which include this one:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
list_files_including = file.list_including # e.g ['test3.h', 'test2.h', 'test4.h', 'subdir/test2.h']
|
126
|
+
files_including = file.files_including # List of Doxyparser::HFile (only for local header files i.e with XML representation in xml_dir)
|
127
|
+
```
|
128
|
+
|
129
|
+
Classes and Structs
|
130
|
+
-------------------
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
struct_def_file = struct.file # Instance of Doxyparser::HFile
|
134
|
+
struct_inner_classes = struct.innerclasses :public # List of Doxyparser::Class
|
135
|
+
struct_inner_structs = struct.innerstructs :protected # List of Doxyparser::Struct
|
136
|
+
struct_enums = struct.innerenums :public # List of Doxyparser::Enum
|
137
|
+
struct_attributes = struct.attributes(:public, :static) # List of Doxyparser::Variable
|
138
|
+
struct_methods = struct.methods(:private, :static) # List of Doxyparser::Function
|
139
|
+
friend_members = struct.friends # List of Doxyparser::Friend
|
140
|
+
type_parameters = struct.template_params # List of Doxyparser::Param
|
141
|
+
type_defs = struct.typedefs :public # List of Doxyparser::Typedef
|
142
|
+
```
|
143
|
+
|
144
|
+
...and as expected for every member:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
struct_methods[0].parent == struct # true
|
148
|
+
```
|
149
|
+
|
150
|
+
The access modifier parameters (:public, :protected, :private) are optional. When none provided then :public is used.
|
151
|
+
For methods and attributes :static can also be specified. When none provided then nil is used.
|
152
|
+
|
153
|
+
Like for namespaces, you can also specify an additional list parameter to query a subset of class/struct members.
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
# Note that the first two params need to be explicitly provided and we use nil instead of false
|
157
|
+
struct_attr = struct.attributes(:protected, nil, ['attribute1', 'attribute2'])
|
158
|
+
```
|
159
|
+
|
160
|
+
|
161
|
+
Functions/Methods, Variables/Attributes, Typedefs and Enums
|
162
|
+
-------------------------------------------------------------
|
163
|
+
|
164
|
+
|
165
|
+
* General Properties:
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
puts myMethod.name # myMethod
|
169
|
+
puts myMethod.parent.name # MyNamespace::Class1
|
170
|
+
puts myMethod.location # /path/to/included/file/myIncludeFile.h:245
|
171
|
+
puts myMethod.definition # virtual void MyNamespace::Class1::myMethod
|
172
|
+
puts myMethod.args # (const Any &anything)
|
173
|
+
```
|
174
|
+
|
175
|
+
|
176
|
+
* Functions and Methods only:
|
177
|
+
|
178
|
+
Consider for example the following definition:
|
179
|
+
|
180
|
+
```shell
|
181
|
+
const String & myFunction(int myInt, std:map<String &, std:list<unsigned char, int *>> myMap = null)
|
182
|
+
```
|
183
|
+
|
184
|
+
After parsing with doxyparser we obtain:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
function_params = myFunction.params # List of Doxyparser::Param
|
188
|
+
first_param_type = function_params[0].type # Instance of Doxyparser::Type
|
189
|
+
puts first_param_type.name # int
|
190
|
+
puts first_param_type.declname # myInt
|
191
|
+
second_param_type = function_params[1].type # Instance of Doxyparser::Type
|
192
|
+
puts second_param_type.name # std:map<String &, std:list<unsigned char, int * > > (full templates support)
|
193
|
+
puts second_param_type.declname # myMap
|
194
|
+
puts second_param_type.value # null
|
195
|
+
return_type = function.type # Instance of Doxyparser::Type
|
196
|
+
puts return_type.name # const String &
|
197
|
+
```
|
198
|
+
|
199
|
+
|
200
|
+
* Methods only:
|
201
|
+
|
202
|
+
```shell
|
203
|
+
MyClass(char * xc);
|
204
|
+
```
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
puts myMethod.name # > MyClass
|
208
|
+
puts myMethod.constructor? # > true
|
209
|
+
puts myMethod.destructor? # > false
|
210
|
+
```
|
211
|
+
|
212
|
+
```shell
|
213
|
+
~MyClass();
|
214
|
+
```
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
puts myMethod.name # > ~MyClass
|
218
|
+
puts myMethod.constructor? # > false
|
219
|
+
puts myMethod.destructor? # > true
|
220
|
+
```
|
221
|
+
|
222
|
+
```shell
|
223
|
+
MyClass* getProp();
|
224
|
+
MyClass* get_prop();
|
225
|
+
MyClass* GetProp();
|
226
|
+
```
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
puts myMethod.name # > getProp/get_prop/GetProp
|
230
|
+
puts myMethod.getter_for # > prop
|
231
|
+
puts myMethod.setter_for # > nil
|
232
|
+
```
|
233
|
+
|
234
|
+
```shell
|
235
|
+
void setProp(MyClass *obj);
|
236
|
+
void set_prop(MyClass *obj);
|
237
|
+
void isProp(MyClass *obj);
|
238
|
+
```
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
puts myMethod.name # > setProp/set_prop/isProp
|
242
|
+
puts myMethod.setter_for # > prop
|
243
|
+
puts myMethod.getter_for # > nil
|
244
|
+
```
|
245
|
+
|
246
|
+
* Enums only:
|
247
|
+
|
248
|
+
```shell
|
249
|
+
enum MyEnum{
|
250
|
+
A, B, C
|
251
|
+
};
|
252
|
+
```
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
puts myEnum.name # > MyEnum
|
256
|
+
puts myEnum.values.join(", ") # > A, B, C
|
257
|
+
```
|
258
|
+
|
259
|
+
...and anonymous enums:
|
260
|
+
|
261
|
+
```shell
|
262
|
+
enum {
|
263
|
+
A, B, C
|
264
|
+
};
|
265
|
+
```
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
puts myEnum.name # > _Enum
|
269
|
+
puts myEnum.values.join(", ") # > A, B, C
|
270
|
+
```
|
271
|
+
|
data/lib/doxyparser.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
require_relative 'util'
|
8
|
+
require_relative 'nodes/node'
|
9
|
+
require_relative 'nodes/compound'
|
10
|
+
require_relative 'nodes/type'
|
11
|
+
require_relative 'nodes/param'
|
12
|
+
require_relative 'nodes/member'
|
13
|
+
require_relative 'nodes/typedef'
|
14
|
+
require_relative 'nodes/friend'
|
15
|
+
require_relative 'nodes/struct'
|
16
|
+
require_relative 'nodes/class'
|
17
|
+
require_relative 'nodes/enum'
|
18
|
+
require_relative 'nodes/hfile'
|
19
|
+
require_relative 'nodes/function'
|
20
|
+
require_relative 'nodes/group'
|
21
|
+
require_relative 'nodes/namespace'
|
22
|
+
require_relative 'nodes/variable'
|
23
|
+
|
24
|
+
|
25
|
+
module Doxyparser
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def parse_namespace basename, xml_dir
|
29
|
+
Doxyparser::Namespace.new :name => basename, :dir => xml_dir
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_group basename, xml_dir
|
33
|
+
Doxyparser::Group.new :name => basename, :dir => xml_dir
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_class basename, xml_dir
|
37
|
+
Doxyparser::Class.new :name => basename, :dir => xml_dir
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_struct basename, xml_dir
|
41
|
+
Doxyparser::Struct.new :name => basename, :dir => xml_dir
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_file basename, xml_dir
|
45
|
+
Doxyparser::HFile.new :name => basename, :dir => xml_dir
|
46
|
+
end
|
47
|
+
|
48
|
+
def gen_xml_docs src_dir, xml_dir, recursive = nil, include_dirs = nil, generate_html = nil
|
49
|
+
|
50
|
+
if include_dirs.nil? || include_dirs.empty?
|
51
|
+
inc_dirs = ''
|
52
|
+
else
|
53
|
+
inc_dirs = include_dirs.join(', ')
|
54
|
+
end
|
55
|
+
recursive = recursive ? 'YES' : 'NO'
|
56
|
+
|
57
|
+
home_dir = Doxyparser::Util.home_dir
|
58
|
+
gen_html = generate_html ? 'YES' : 'NO'
|
59
|
+
proj_name = File.basename src_dir
|
60
|
+
doxyfile = "# Doxyfile 1.7.6.1\n\n"
|
61
|
+
doxyfile << "# Project related configuration options\n\n"
|
62
|
+
doxyfile << %Q{PROJECT_NAME\t\t= "#{proj_name}"\nINPUT\t\t\t\t= #{src_dir}\nGENERATE_HTML\t\t= #{gen_html}\n}
|
63
|
+
doxyfile << %Q{RECURSIVE\t\t\t= #{recursive}\nINCLUDE_PATH\t\t= #{inc_dirs}\n\n}
|
64
|
+
doxyfile << "# Default doxygen configuration options\n\n"
|
65
|
+
doxyfile << Doxyparser::Util.read_file(home_dir+'/resources/Doxyfile')
|
66
|
+
doxyfile_path = xml_dir+'/Doxyfile'
|
67
|
+
FileUtils.mkdir_p(xml_dir)
|
68
|
+
Doxyparser::Util.write_file(doxyfile_path, doxyfile)
|
69
|
+
Dir.chdir(xml_dir)
|
70
|
+
command = %Q{doxygen < #{doxyfile_path}}
|
71
|
+
output = IO.popen(command)
|
72
|
+
output.readlines
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/nodes/class.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Doxyparser
|
2
|
+
|
3
|
+
class Compound < Node
|
4
|
+
|
5
|
+
attr_reader :xml_path
|
6
|
+
|
7
|
+
def new_unnamed
|
8
|
+
@unnamed += 1
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def init_attributes
|
14
|
+
super
|
15
|
+
@unnamed = 0
|
16
|
+
if @node
|
17
|
+
@xml_path = %Q{#{@dir}/#{self.refid}.xml}
|
18
|
+
else
|
19
|
+
compute_path
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_name
|
24
|
+
@node.child.content
|
25
|
+
end
|
26
|
+
|
27
|
+
def doc
|
28
|
+
if @doc.nil?
|
29
|
+
parse
|
30
|
+
end
|
31
|
+
@doc
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse
|
35
|
+
raise "No file found at this location: #{@xml_path} for node #{self.class.name} #{@name}" unless File.exists? @xml_path
|
36
|
+
File.open(@xml_path) { |xml_doc|
|
37
|
+
@doc=Nokogiri::XML(xml_doc)
|
38
|
+
}
|
39
|
+
self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/nodes/enum.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Doxyparser
|
2
|
+
|
3
|
+
class Enum < Member
|
4
|
+
|
5
|
+
def values
|
6
|
+
ret=[]
|
7
|
+
xpath("enumvalue/name").each { |v| ret << v.child.content }
|
8
|
+
ret
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def find_name
|
14
|
+
super.gsub(/@\d*/) {
|
15
|
+
num = parent.new_unnamed
|
16
|
+
'_Enum' + (num == 1 ? '' : num.to_s)
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|