Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/docurium.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,11 @@ def parse_headers(index, version)
end

data = init_data(version)
parser = DocParser.new
headers.each do |header|
records = parser.parse_file(header, files)
update_globals!(data, records)
DocParser.with_files(files, :prefix => version) do |parser|
headers.each do |header|
records = parser.parse_file(header)
update_globals!(data, records)
end
end

data[:groups] = group_functions!(data)
Expand Down
35 changes: 23 additions & 12 deletions lib/docurium/docparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,44 @@ def find_clang_includes
end
end

# Entry point for this parser
# Parse `filename` out of the hash `files`
def parse_file(orig_filename, files)
def self.with_files(files, opts = {})
parser = self.new(files, opts)
yield parser
parser.cleanup!
end

def initialize(files, opts = {})
# unfortunately Clang wants unsaved files to exist on disk, so
# we need to create at least empty files for each unsaved file
# we're given.

tmpdir = Dir.mktmpdir()

unsaved = files.map do |name, contents|
full_path = File.join(tmpdir, name)
prefix = (opts[:prefix] ? opts[:prefix] + "-" : nil)
@tmpdir = Dir.mktmpdir(prefix)
@unsaved = files.map do |name, contents|
full_path = File.join(@tmpdir, name)
dirname = File.dirname(full_path)
FileUtils.mkdir_p(dirname) unless Dir.exist? dirname
File.new(full_path, File::CREAT).close()

UnsavedFile.new(full_path, contents)
end
end

def cleanup!
FileUtils.remove_entry(@tmpdir)
end

# Entry point for this parser
# Parse `filename` out of the hash `files`
def parse_file(orig_filename)

includes = find_clang_includes + [tmpdir]
includes = find_clang_includes + [@tmpdir]

# Override the path we want to filter by
filename = File.join(tmpdir, orig_filename)
filename = File.join(@tmpdir, orig_filename)
args = includes.map { |path| "-I#{path}" }
tu = Index.new(true, true).parse_translation_unit(filename, args, unsaved, {:detailed_preprocessing_record => 1})
args << '-ferror-limit=1'

FileUtils.remove_entry(tmpdir)
tu = Index.new(true, true).parse_translation_unit(filename, args, @unsaved, {:detailed_preprocessing_record => 1})

recs = []

Expand Down
12 changes: 8 additions & 4 deletions test/parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

class ParserTest < Minitest::Test

def setup
@parser = Docurium::DocParser.new
def teardown
@parser.cleanup! if @parser
end

# e.g. parse('git2/refs.h')
# contents is either a string (the contents of "path")
# or a hash of paths => contents
def parse(path, contents)
@parser.parse_file(path, [[path, contents]])
contents = [[path, contents]] if contents.is_a? String
@parser = Docurium::DocParser.new(contents)
@parser.parse_file(path)
end

def test_single_function
Expand Down Expand Up @@ -122,7 +126,7 @@ def test_parsing_with_extern
GIT_EXTERN(int) some_public_function(int val);
EOF

actual = @parser.parse_file(name_b, [[name_a, contents_a], [name_b, contents_b]])
actual = parse(name_b, [[name_a, contents_a], [name_b, contents_b]])
# "Fix" the path so we remove the temp dir
actual[0][:file] = File.split(actual[0][:file])[-1]

Expand Down