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
1 change: 1 addition & 0 deletions src/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub enum ItemFormat {
#[derive(Debug)]
pub struct GcnoBuffers {
pub stem: String,
pub full_path: Option<PathBuf>,
pub gcno_buf: Vec<u8>,
pub gcda_buf: Vec<Vec<u8>>,
}
Expand Down
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,17 @@ fn add_results(
}
}

/// Replace file paths which have more .. components than normalize_path can handle.
fn rename_external_files(results: &mut [(String, CovResult)], full_path: Option<&Path>) {
if let Some(gcno_parent) = full_path.and_then(Path::parent) {
for (file, _) in results.iter_mut() {
if normalize_path(Path::new(file)).is_none() {
*file = gcno_parent.join(&file).to_str().unwrap().to_string();
}
}
}
}

fn rename_single_files(results: &mut [(String, CovResult)], stem: &str) {
// sometimes the gcno just contains foo.c
// so in such case (with option --guess-directory-when-missing)
Expand Down Expand Up @@ -244,6 +255,7 @@ pub fn consumer(
new_results
};

rename_external_files(&mut new_results, Some(&gcno_path));
if guess_directory {
rename_single_files(&mut new_results, &stem);
}
Expand All @@ -258,6 +270,7 @@ pub fn consumer(
branch_enabled,
) {
Ok(mut r) => {
rename_external_files(&mut r, buffers.full_path.as_deref());
if guess_directory {
rename_single_files(&mut r, &buffers.stem);
}
Expand Down
21 changes: 16 additions & 5 deletions src/llvm_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,22 +446,33 @@ mod tests {

let lcov = String::from_utf8_lossy(&lcovs[0]);

let lcov_entries = [
let mut lcov_entries = vec![
"FNF:1", // # of function found
"FNH:1", // # of function hit
"DA:1,2", // Line 1 hit 2 times
"DA:2,2", // Line 2 hit 2 times
"DA:3,1", // Line 3 hit 1 time
"DA:4,1", // Line 4 hit 1 time
"DA:5,1", // Line 5 hit 1 time
"DA:6,1", // Line 6 hit 1 time
"DA:7,2", // Line 7 hit 2 time
"BRF:0", // # of branch found
"BRH:0", // # of branch hit
"LF:7", // # of line found
"LH:7", // # of line hit
];

// Starting with rustc nightly-2026-09-07, lines 4 and 6 are not counted as code lines anymore.
if lcov.contains("DA:4,1\n") {
Comment thread
nicolas-guichard marked this conversation as resolved.
lcov_entries.extend_from_slice(&[
"DA:4,1", // Line 4 hit 1 time
"DA:6,1", // Line 6 hit 1 time
"LF:7", // # of line found
"LH:7", // # of line hit
]);
} else {
lcov_entries.extend_from_slice(&[
"LF:5", // # of line found
"LH:5", // # of line hit
]);
};

for entry in lcov_entries {
assert!(lcov.contains(&format!("{entry}\n")));
}
Expand Down
29 changes: 19 additions & 10 deletions src/producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ pub struct Archive {
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub struct GCNOStem {
pub struct GCNOInfos {
pub stem: String,
/// Full path to the GCNO file, unavailable when the file is in an archive.
pub full_path: Option<PathBuf>,
pub llvm: bool,
}

Expand Down Expand Up @@ -59,7 +61,8 @@ impl Archive {
&'a self,
file: Option<&mut impl Read>,
path: &Path,
gcno_stem_archives: &RefCell<FxHashMap<GCNOStem, &'a Archive>>,
full_path: Option<&Path>,
gcno_stem_archives: &RefCell<FxHashMap<GCNOInfos, &'a Archive>>,
gcda_stem_archives: &RefCell<FxHashMap<String, Vec<&'a Archive>>>,
profdatas: &RefCell<FxHashMap<String, Vec<&'a Archive>>>,
profraws: &RefCell<FxHashMap<String, Vec<&'a Archive>>>,
Expand All @@ -75,8 +78,9 @@ impl Archive {
let llvm = is_llvm || Archive::check_file(file, &Archive::is_gcno_llvm);
let filename = clean_path(&path.with_extension(""));
gcno_stem_archives.borrow_mut().insert(
GCNOStem {
GCNOInfos {
stem: filename,
full_path: full_path.map(ToOwned::to_owned),
llvm,
},
self,
Expand Down Expand Up @@ -162,7 +166,7 @@ impl Archive {

pub fn explore<'a>(
&'a mut self,
gcno_stem_archives: &RefCell<FxHashMap<GCNOStem, &'a Archive>>,
gcno_stem_archives: &RefCell<FxHashMap<GCNOInfos, &'a Archive>>,
gcda_stem_archives: &RefCell<FxHashMap<String, Vec<&'a Archive>>>,
profdatas: &RefCell<FxHashMap<String, Vec<&'a Archive>>>,
profraws: &RefCell<FxHashMap<String, Vec<&'a Archive>>>,
Expand All @@ -181,6 +185,7 @@ impl Archive {
self.handle_file(
Some(&mut file),
&path,
None,
gcno_stem_archives,
gcda_stem_archives,
profdatas,
Expand Down Expand Up @@ -208,6 +213,7 @@ impl Archive {
self.handle_file(
file.as_mut(),
path,
Some(full_path),
gcno_stem_archives,
gcda_stem_archives,
profdatas,
Expand All @@ -228,6 +234,7 @@ impl Archive {
self.handle_file(
file.as_mut(),
full_path,
Some(full_path),
gcno_stem_archives,
gcda_stem_archives,
profdatas,
Expand Down Expand Up @@ -326,7 +333,7 @@ impl Archive {

fn gcno_gcda_producer(
tmp_dir: &Path,
gcno_stem_archives: &FxHashMap<GCNOStem, &Archive>,
gcno_stem_archives: &FxHashMap<GCNOInfos, &Archive>,
gcda_stem_archives: &FxHashMap<String, Vec<&Archive>>,
sender: &JobSender,
ignore_orphan_gcno: bool,
Expand All @@ -341,13 +348,13 @@ fn gcno_gcda_producer(
.unwrap()
};

for (gcno_stem, gcno_archive) in gcno_stem_archives {
let stem = &gcno_stem.stem;
for (gcno_infos, gcno_archive) in gcno_stem_archives {
let stem = &gcno_infos.stem;
if let Some(gcda_archives) = gcda_stem_archives.get(stem) {
let gcno_archive = *gcno_archive;
let gcno = format!("{stem}.gcno").to_string();
let physical_gcno_path = tmp_dir.join(format!("{}_{}.gcno", stem, 1));
if gcno_stem.llvm {
if gcno_infos.llvm {
let mut gcda_buffers: Vec<Vec<u8>> = Vec::with_capacity(gcda_archives.len());
if let Some(gcno_buffer) = gcno_archive.read(&gcno) {
for gcda_archive in gcda_archives {
Expand All @@ -359,6 +366,7 @@ fn gcno_gcda_producer(
send_job(
ItemType::Buffers(GcnoBuffers {
stem: stem.clone(),
full_path: gcno_infos.full_path.clone(),
gcno_buf: gcno_buffer,
gcda_buf: gcda_buffers,
}),
Expand Down Expand Up @@ -391,11 +399,12 @@ fn gcno_gcda_producer(
} else if !ignore_orphan_gcno {
let gcno_archive = *gcno_archive;
let gcno = format!("{stem}.gcno").to_string();
if gcno_stem.llvm {
if gcno_infos.llvm {
if let Some(gcno_buf) = gcno_archive.read(&gcno) {
send_job(
ItemType::Buffers(GcnoBuffers {
stem: stem.clone(),
full_path: gcno_infos.full_path.clone(),
gcno_buf,
gcda_buf: Vec::new(),
}),
Expand Down Expand Up @@ -562,7 +571,7 @@ pub fn producer(
});
}

let gcno_stems_archives: RefCell<FxHashMap<GCNOStem, &Archive>> =
let gcno_stems_archives: RefCell<FxHashMap<GCNOInfos, &Archive>> =
RefCell::new(FxHashMap::default());
let gcda_stems_archives: RefCell<FxHashMap<String, Vec<&Archive>>> =
RefCell::new(FxHashMap::default());
Expand Down
Loading