docurium 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 254c929d02d15703e7a653b44957e8a6e57dfadb3a0d2b62a419e31f44e8cda1
4
- data.tar.gz: 9dc4b04e2e9b705448e3ff50bb4480fb5fd5466472dcf24a6b2823fdcaf9219d
3
+ metadata.gz: 4ace5599ba2e3394f8edf0f6dbe0a388c163a11f3b55548c1048c386c8e18c54
4
+ data.tar.gz: e4bf9b423afd1a32079b8c5722ab64f7140da1d43072bc7d66418a9c8bfb9601
5
5
  SHA512:
6
- metadata.gz: 60e0579913e6f55fc4d34b5c0858cdaca36948425419a5023f080c4903ad1ad22ae62b53c338beee74247654d21400527c3d95cc96a7b4d5ca6b9e5a7110007b
7
- data.tar.gz: cb64247b31745da479be5599fcf04f8b02a6337ea4e4867acee517b424a9492b1f9cec04b7cf594fa1161008fcf4f7db31c7a9527992f94fdbfb88aa2582d519
6
+ metadata.gz: a0d4bf587364d3436d28dbab2f4bc5785c52510dcae70bae4f05ca89181786286e5b3072be86984ad5c216f64dccbbd76e02c35db8cb5022bef53907eba041f8
7
+ data.tar.gz: 0b7c46c6776e92c9dd233c8fe7b48fd9791dad0e26c105169fc3b8c8ff79ba57e9f72c152b8e6a53c0f8fcbdea8c9d2cc9eedb63b4eae91d70d76d7bbd958e74
@@ -0,0 +1,42 @@
1
+ name: Docurium
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: [head, 3.0, 2.7, 2.6]
16
+ llvm: ["6.0", 7, 8, 9, 10]
17
+ os: [ ubuntu-18.04 ]
18
+ include:
19
+ - os: macos-latest
20
+ ruby: 2.6
21
+ llvm: ~ # system
22
+
23
+ name: Ruby ${{ matrix.ruby }} / LLVM ${{ matrix.llvm }} on ${{ matrix.os }}
24
+ runs-on: ${{ matrix.os }}
25
+ continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
26
+
27
+ steps:
28
+ - uses: actions/checkout@v2
29
+ - name: Install Linux packages
30
+ if: runner.os == 'Linux'
31
+ run: |
32
+ sudo apt update
33
+ sudo apt install -y python-pygments libclang-${{ matrix.llvm }}-dev llvm-${{ matrix.llvm }} clang-${{ matrix.llvm }}
34
+ - name: Set up Ruby ${{ matrix.ruby }}
35
+ uses: ruby/setup-ruby@v1
36
+ with:
37
+ ruby-version: ${{ matrix.ruby }}
38
+ bundler-cache: true
39
+ - name: Run tests
40
+ run: |
41
+ [ -x /usr/bin/llvm-config-${{ matrix.llvm }} ] && export LLVM_CONFIG=llvm-config-${{ matrix.llvm }}
42
+ bundle exec rake
data/Gemfile CHANGED
@@ -1,7 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- platforms :rbx do
4
- gem 'rubysl', '~> 2.2'
3
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.0.0')
4
+ platforms :rbx do
5
+ gem 'rubysl', '~> 2.2'
6
+ end
5
7
  end
6
8
 
7
9
  gemspec
data/bin/cm CHANGED
@@ -14,12 +14,26 @@ desc 'Generate HTML documentation'
14
14
  long_desc 'Generate HTML docs from a Docurium config file'
15
15
  command :doc do |c|
16
16
  c.flag :for, :desc => "The version to generate", :multiple => true
17
+ c.switch [:n, "dry-run"], :desc => "Dry-run"
18
+ c.switch [:d, "debug"], :desc => "Enable debug log"
19
+ c.flag "debug-file", :desc => "Enable debug output for header", :multiple => true
20
+ c.flag "debug-function", :desc => "Show debug output when processing function", :multiple => true
21
+ c.flag "debug-type", :desc => "Show debug output when processing type", :multiple => true
17
22
  c.action do |global_options,options,args|
18
23
  file = args.first
19
24
  Docurium::CLI.doc(file, options)
20
25
  end
21
26
  end
22
27
 
28
+ desc 'Check documentation for warnings'
29
+ long_desc 'Check a project\'s documentation for issues'
30
+ command :check do |c|
31
+ c.action do |global_options,options,args|
32
+ file = args.first
33
+ Docurium::CLI.check(file, options)
34
+ end
35
+ end
36
+
23
37
  desc 'Generate Docurium config file template'
24
38
  long_desc 'Generate Docurium config file template'
25
39
  command :gen do |c|
data/docurium.gemspec CHANGED
@@ -17,10 +17,11 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency "mustache", "~> 1.1"
18
18
  s.add_dependency "rocco", "~>0.8"
19
19
  s.add_dependency "gli", "~>2.5"
20
- s.add_dependency "rugged", "~>0.21"
20
+ s.add_dependency "rugged", "~>1.1"
21
21
  s.add_dependency "redcarpet", "~>3.0"
22
22
  s.add_dependency "ffi-clang", "~> 0.5"
23
- s.add_development_dependency "rake", "~> 12"
23
+ s.add_dependency "parallel", "~> 1.20"
24
+ s.add_development_dependency "rake", "~> 13"
24
25
  s.add_development_dependency "minitest", "~> 5.11"
25
26
 
26
27
  s.files = `git ls-files`.split("\n")
data/lib/docurium/cli.rb CHANGED
@@ -2,8 +2,13 @@ class Docurium
2
2
  class CLI
3
3
 
4
4
  def self.doc(idir, options)
5
+ doc = Docurium.new(idir, options)
6
+ doc.generate_docs
7
+ end
8
+
9
+ def self.check(idir, options)
5
10
  doc = Docurium.new(idir)
6
- doc.generate_docs(options)
11
+ doc.check_warnings(options)
7
12
  end
8
13
 
9
14
  def self.gen(file)
@@ -0,0 +1,41 @@
1
+ $debug_stack = [false]
2
+
3
+ def debug_enabled
4
+ $debug_stack[-1]
5
+ end
6
+
7
+ def debug(str = nil)
8
+ puts str if debug_enabled
9
+ end
10
+
11
+ def debug_enable
12
+ $debug_stack.push true
13
+ end
14
+
15
+ def debug_silence
16
+ $debug_stack.push false
17
+ end
18
+
19
+ def debug_set val
20
+ $debug_stack.push val
21
+ end
22
+
23
+ def debug_pass
24
+ $debug_stack.push debug_enabled
25
+ end
26
+
27
+ def debug_restore
28
+ $debug_stack.pop
29
+ end
30
+
31
+ def with_debug(&block)
32
+ debug_enable
33
+ block.call
34
+ debug_restore
35
+ end
36
+
37
+ def without_debug(&block)
38
+ debug_silence
39
+ block.call
40
+ debug_restore
41
+ end
@@ -1,46 +1,87 @@
1
1
  require 'tempfile'
2
2
  require 'fileutils'
3
3
  require 'ffi/clang'
4
+ require 'open3'
4
5
  include FFI::Clang
5
6
 
6
7
  class Docurium
7
8
  class DocParser
8
- # Entry point for this parser
9
- # Parse `filename` out of the hash `files`
10
- def parse_file(orig_filename, files)
9
+ # The include directory where clang has its basic type definitions is not
10
+ # included in our default search path, so as a workaround we execute clang
11
+ # in verbose mode and grab its include paths from the output.
12
+ def find_clang_includes
13
+ @includes ||=
14
+ begin
15
+ clang = if ENV["LLVM_CONFIG"]
16
+ bindir = `#{ENV["LLVM_CONFIG"]} --bindir`.strip
17
+ "#{bindir}/clang"
18
+ else
19
+ "clang"
20
+ end
21
+
22
+ output, _status = Open3.capture2e("#{clang} -v -x c -", :stdin_data => "")
23
+ includes = []
24
+ output.each_line do |line|
25
+ if line =~ %r{^\s+/(.*usr|.*lib/clang.*)/include}
26
+ includes << line.strip
27
+ end
28
+ end
29
+
30
+ includes
31
+ end
32
+ end
11
33
 
34
+ def self.with_files(files, opts = {})
35
+ parser = self.new(files, opts)
36
+ yield parser
37
+ parser.cleanup!
38
+ end
39
+
40
+ def initialize(files, opts = {})
12
41
  # unfortunately Clang wants unsaved files to exist on disk, so
13
42
  # we need to create at least empty files for each unsaved file
14
43
  # we're given.
15
44
 
16
- tmpdir = Dir.mktmpdir()
17
-
18
- unsaved = files.map do |name, contents|
19
- full_path = File.join(tmpdir, name)
45
+ prefix = (opts[:prefix] ? opts[:prefix] + "-" : nil)
46
+ @tmpdir = Dir.mktmpdir(prefix)
47
+ @unsaved = files.map do |name, contents|
48
+ full_path = File.join(@tmpdir, name)
20
49
  dirname = File.dirname(full_path)
21
50
  FileUtils.mkdir_p(dirname) unless Dir.exist? dirname
22
51
  File.new(full_path, File::CREAT).close()
23
-
24
52
  UnsavedFile.new(full_path, contents)
25
53
  end
54
+ end
26
55
 
27
- # Override the path we want to filter by
28
- filename = File.join(tmpdir, orig_filename)
29
- tu = Index.new.parse_translation_unit(filename, ["-DDOCURIUM=1"], unsaved, {:detailed_preprocessing_record => 1})
56
+ def cleanup!
57
+ FileUtils.remove_entry(@tmpdir)
58
+ end
30
59
 
31
- FileUtils.remove_entry(tmpdir)
60
+ # Entry point for this parser
61
+ # Parse `filename` out of the hash `files`
62
+ def parse_file(orig_filename, opts = {})
32
63
 
33
- cursor = tu.cursor
64
+ includes = find_clang_includes + [@tmpdir]
65
+
66
+ # Override the path we want to filter by
67
+ filename = File.join(@tmpdir, orig_filename)
68
+ debug_enable if opts[:debug]
69
+ debug "parsing #{filename} #{@tmpdir}"
70
+ args = includes.map { |path| "-I#{path}" }
71
+ args << '-ferror-limit=1'
72
+
73
+ tu = Index.new(true, true).parse_translation_unit(filename, args, @unsaved, {:detailed_preprocessing_record => 1})
34
74
 
35
75
  recs = []
36
76
 
37
- cursor.visit_children do |cursor, parent|
38
- #puts "visiting #{cursor.kind} - #{cursor.spelling}"
77
+ tu.cursor.visit_children do |cursor, parent|
39
78
  location = cursor.location
40
79
  next :continue if location.file == nil
41
80
  next :continue unless location.file == filename
42
81
 
43
- #puts "for file #{location.file} #{cursor.kind} #{cursor.spelling} #{cursor.comment.kind} #{location.line}"
82
+ loc = "%d:%d-%d:%d" % [cursor.extent.start.line, cursor.extent.start.column, cursor.extent.end.line, cursor.extent.end.column]
83
+ debug "#{cursor.location.file}:#{loc} - visiting #{cursor.kind}: #{cursor.spelling}, comment is #{cursor.comment.kind}"
84
+
44
85
  #cursor.visit_children do |c|
45
86
  # puts " child #{c.kind}, #{c.spelling}, #{c.comment.kind}"
46
87
  # :continue
@@ -57,25 +98,38 @@ class Docurium
57
98
  :tdef => nil,
58
99
  }
59
100
 
60
- case cursor.kind
101
+ extract = case cursor.kind
61
102
  when :cursor_function
62
- #puts "have function"
63
- rec.merge! extract_function(cursor)
103
+ debug "have function #{cursor.spelling}"
104
+ rec.update extract_function(cursor)
64
105
  when :cursor_enum_decl
65
- rec.merge! extract_enum(cursor)
106
+ debug "have enum #{cursor.spelling}"
107
+ rec.update extract_enum(cursor)
66
108
  when :cursor_struct
67
- #puts "raw struct"
68
- rec.merge! extract_struct(cursor)
109
+ debug "have struct #{cursor.spelling}"
110
+ rec.update extract_struct(cursor)
69
111
  when :cursor_typedef_decl
70
- rec.merge! extract_typedef(cursor)
112
+ debug "have typedef #{cursor.spelling} #{cursor.underlying_type.spelling}"
113
+ rec.update extract_typedef(cursor)
71
114
  else
72
115
  raise "No idea how to deal with #{cursor.kind}"
73
116
  end
74
117
 
118
+ rec.merge! extract
119
+
75
120
  recs << rec
76
121
  :continue
77
122
  end
78
123
 
124
+ if debug_enabled
125
+ puts "parse_file: parsed #{recs.size} records for #{filename}:"
126
+ recs.each do |r|
127
+ puts "\t#{r}"
128
+ end
129
+ end
130
+
131
+ debug_restore
132
+
79
133
  recs
80
134
  end
81
135
 
@@ -149,15 +203,27 @@ class Docurium
149
203
 
150
204
  def extract_subject_desc(comment)
151
205
  subject = comment.child.text
152
- paras = comment.find_all { |cmt| cmt.kind == :comment_paragraph }.drop(1).map { |p| p.map(&:text).join() }
206
+ debug "\t\tsubject: #{subject}"
207
+ paras = comment.find_all { |cmt| cmt.kind == :comment_paragraph }.drop(1).map { |p| p.text }
153
208
  desc = paras.join("\n\n")
209
+ debug "\t\tdesc: #{desc}"
154
210
  return subject, desc
155
211
  end
156
212
 
157
213
  def extract_function(cursor)
158
214
  comment = cursor.comment
159
215
 
160
- #puts "looking at function #{cursor.spelling}, #{cursor.display_name}"
216
+ $buggy_functions = %w()
217
+ debug_set ($buggy_functions.include? cursor.spelling)
218
+ if debug_enabled
219
+ puts "\tlooking at function #{cursor.spelling}, #{cursor.display_name}"
220
+ puts "\tcomment: #{comment}, #{comment.kind}"
221
+ cursor.visit_children do |cur, parent|
222
+ puts "\t\tchild: #{cur.spelling}, #{cur.kind}"
223
+ :continue
224
+ end
225
+ end
226
+
161
227
  cmt = extract_function_comment(comment)
162
228
  args = extract_function_args(cursor, cmt)
163
229
  #args = args.reject { |arg| arg[:comment].nil? }
@@ -182,6 +248,7 @@ class Docurium
182
248
  decl = "#{ret[:type]} #{cursor.spelling}(#{argline})"
183
249
  body = "#{decl};"
184
250
 
251
+ debug_restore
185
252
  #puts cursor.display_name
186
253
  # Return the format that docurium expects
187
254
  {
@@ -200,6 +267,7 @@ class Docurium
200
267
 
201
268
  def extract_function_comment(comment)
202
269
  subject, desc = extract_subject_desc(comment)
270
+ debug "\t\textract_function_comment: #{comment}, #{comment.kind}, #{subject}, #{desc}"
203
271
 
204
272
  args = {}
205
273
  (comment.find_all { |cmt| cmt.kind == :comment_param_command }).each do |param|
@@ -275,7 +343,7 @@ class Docurium
275
343
  :continue
276
344
  end
277
345
 
278
- #puts "struct value #{values}"
346
+ debug "\tstruct value #{values}"
279
347
 
280
348
  rec = {
281
349
  :type => :struct,
@@ -1,7 +1,4 @@
1
1
  # adding some stuff I need
2
2
  class Rocco::Layout
3
3
  attr_accessor :version
4
- def version
5
- @version
6
- end
7
4
  end
@@ -1,3 +1,3 @@
1
1
  class Docurium
2
- Version = VERSION = '0.6.0'
2
+ Version = VERSION = '0.7.0'
3
3
  end