docurium 0.6.0 → 0.7.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.
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