AdamNiederer / cov

An emacs extension for displaying coverage data on your code
GNU General Public License v3.0
76 stars 16 forks source link

gcov parser seems to be broken. #37

Closed john-w-phillips closed 2 years ago

john-w-phillips commented 3 years ago

The gcov parsing function, cov--gcov-parse, returns a cons-cell incompatible with the assoc statement in cov--get-buffer-coverage.

Here is cov--gcov-parse:

(defun cov--gcov-parse (&optional buffer)
  "Parse gcov coverage from gcov file in BUFFER.
Read from `current-buffer' if BUFFER is nil. Return a list
`((FILE . ((LINE-NUM TIMES-RAN) ...)))'. Unused lines (TIMES-RAN
'-') are filtered out."
  (with-current-buffer (or buffer (current-buffer))
    ;; The buffer is _not_ automatically widened. It is possible to
    ;; read just a portion of the buffer by narrowing it first.
    (let ((line-re (rx line-start
                       ;; note the group numbers are in reverse order
                       ;; in the first alternative
                       (or (seq (* blank) (group-n 2 (+ (in digit ?#))) ?:
                                (* blank) (group-n 1 (+ digit)) ?:)
                           (seq "lcount:" (group-n 1 (+ digit)) ?, (group-n 2 (+ digit))))))
          ;; Derive the name of the covered file from the filename of
          ;; the coverage file.
          (filename (file-name-sans-extension (f-filename cov-coverage-file))))
      (save-excursion
        (save-match-data
          (goto-char (point-min))
          (list (cons filename
                      (cl-loop
                       while (re-search-forward line-re nil t)
                       collect (list (string-to-number (match-string 1))
                                     (string-to-number (match-string 2)))))))))))

The filename variable is specifically created to not have an extension. So a file /some/path/src/namespace_a/namespace_b/X.hpp will be in the alist as just "X". However, cov--get-buffer-coverage after extracting the coverage alist from the structure in the hashtable, assocs it using f-filename, which includes the suffix, along with portions of the pathname:

;; ... the rest of cov--get-buffer-coverage ...
        (let ((common (f-common-parent (list file (buffer-file-name)))))
          (cdr (assoc (string-remove-prefix common (buffer-file-name))
                      (cov-data-coverage stored-data))))))))

Issues of the path scheme that the code assumes the project must have aside, this has no chance of working with the gcov parser, unless I'm missing something? That's certainly possible.

snogge commented 2 years ago

Is this the same as #23 ? There is a suggested workaround in that issue that works at least for some usecases. I started working on a fix for issue 23 but I never got around to completing it. You could try it out here https://github.com/snogge/cov/commit/f3729b318e75a70313a1613994880cf41f6e4e38 and let me know if it works for you.

snogge commented 2 years ago

filename is the coverage data file, for a source file /some/path/src/namespace_a/namespace_b/X.hpp that would typically be /some/path/src/namespace_a/namespace_b/X.hpp.gcov. And since file-name-sans-extension only removes one extension, it would still be X.hpp that is returned from cov--gcov-parse.

You are bitten by #23. The fix I linked to in my last response might work for you, but it only fixes #23 for gcov. I'm working on a fix to only use absolute paths in the hash table and coverage data. This should fix #23 properly.

snogge commented 2 years ago

Duplicate of #23 .