Commit b9eaba7c authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '0.29.x'

parents f00cd893 d6341966
...@@ -82,7 +82,7 @@ class Plugin(CoveragePlugin): ...@@ -82,7 +82,7 @@ class Plugin(CoveragePlugin):
# is not from the main .pyx file but a file with a different # is not from the main .pyx file but a file with a different
# name than the .c file (which prevents us from finding the # name than the .c file (which prevents us from finding the
# .c file) # .c file)
_, code = self._parse_lines(c_file, filename) _, code = self._read_source_lines(c_file, filename)
if code is None: if code is None:
return None # no source found return None # no source found
...@@ -104,7 +104,7 @@ class Plugin(CoveragePlugin): ...@@ -104,7 +104,7 @@ class Plugin(CoveragePlugin):
c_file, _ = self._find_source_files(filename) c_file, _ = self._find_source_files(filename)
if not c_file: if not c_file:
return None # unknown file return None # unknown file
rel_file_path, code = self._parse_lines(c_file, filename) rel_file_path, code = self._read_source_lines(c_file, filename)
if code is None: if code is None:
return None # no source found return None # no source found
return CythonModuleReporter(c_file, filename, rel_file_path, code) return CythonModuleReporter(c_file, filename, rel_file_path, code)
...@@ -170,14 +170,14 @@ class Plugin(CoveragePlugin): ...@@ -170,14 +170,14 @@ class Plugin(CoveragePlugin):
for filename in os.listdir(dir_path): for filename in os.listdir(dir_path):
ext = splitext(filename)[1].lower() ext = splitext(filename)[1].lower()
if ext in C_FILE_EXTENSIONS: if ext in C_FILE_EXTENSIONS:
self._parse_lines(os.path.join(dir_path, filename), source_file) self._read_source_lines(os.path.join(dir_path, filename), source_file)
if source_file in self._c_files_map: if source_file in self._c_files_map:
return return
# not found? then try one package up # not found? then try one package up
if is_package_dir(dir_path): if is_package_dir(dir_path):
self._find_c_source_files(os.path.dirname(dir_path), source_file) self._find_c_source_files(os.path.dirname(dir_path), source_file)
def _parse_lines(self, c_file, sourcefile): def _read_source_lines(self, c_file, sourcefile):
""" """
Parse a Cython generated C/C++ source file and find the executable lines. Parse a Cython generated C/C++ source file and find the executable lines.
Each executable line starts with a comment header that states source file Each executable line starts with a comment header that states source file
...@@ -188,6 +188,24 @@ class Plugin(CoveragePlugin): ...@@ -188,6 +188,24 @@ class Plugin(CoveragePlugin):
if c_file in self._parsed_c_files: if c_file in self._parsed_c_files:
code_lines = self._parsed_c_files[c_file] code_lines = self._parsed_c_files[c_file]
else: else:
code_lines = self._parse_cfile_lines(c_file)
self._parsed_c_files[c_file] = code_lines
if self._c_files_map is None:
self._c_files_map = {}
for filename, code in code_lines.items():
abs_path = _find_dep_file_path(c_file, filename)
self._c_files_map[abs_path] = (c_file, filename, code)
if sourcefile not in self._c_files_map:
return (None,) * 2 # e.g. shared library file
return self._c_files_map[sourcefile][1:]
def _parse_cfile_lines(self, c_file):
"""
Parse a C file and extract all source file lines that generated executable code.
"""
match_source_path_line = re.compile(r' */[*] +"(.*)":([0-9]+)$').match match_source_path_line = re.compile(r' */[*] +"(.*)":([0-9]+)$').match
match_current_code_line = re.compile(r' *[*] (.*) # <<<<<<+$').match match_current_code_line = re.compile(r' *[*] (.*) # <<<<<<+$').match
match_comment_end = re.compile(r' *[*]/$').match match_comment_end = re.compile(r' *[*]/$').match
...@@ -202,6 +220,7 @@ class Plugin(CoveragePlugin): ...@@ -202,6 +220,7 @@ class Plugin(CoveragePlugin):
code_lines = defaultdict(dict) code_lines = defaultdict(dict)
executable_lines = defaultdict(set) executable_lines = defaultdict(set)
current_filename = None current_filename = None
with open(c_file) as lines: with open(c_file) as lines:
lines = iter(lines) lines = iter(lines)
for line in lines: for line in lines:
...@@ -232,19 +251,7 @@ class Plugin(CoveragePlugin): ...@@ -232,19 +251,7 @@ class Plugin(CoveragePlugin):
dead_lines = set(lines).difference(executable_lines.get(filename, ())) dead_lines = set(lines).difference(executable_lines.get(filename, ()))
for lineno in dead_lines: for lineno in dead_lines:
del lines[lineno] del lines[lineno]
return code_lines
self._parsed_c_files[c_file] = code_lines
if self._c_files_map is None:
self._c_files_map = {}
for filename, code in code_lines.items():
abs_path = _find_dep_file_path(c_file, filename)
self._c_files_map[abs_path] = (c_file, filename, code)
if sourcefile not in self._c_files_map:
return (None,) * 2 # e.g. shared library file
return self._c_files_map[sourcefile][1:]
class CythonModuleTracer(FileTracer): class CythonModuleTracer(FileTracer):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment