cov/lib.rs
1//! `cov` is a GCNO/GCDA parser. GCNO/GCDA are source code coverage file formats produced by GCC and LLVM-based
2//! compilers, including `rustc`.
3//!
4//! GCNO (gcov notes) files are created by rustc when given the `-Z profile` flag. The GCNO files encode the structure
5//! of every function in the program, known as the [control-flow graph (CFG)][cfg]. The GCNO also contains the filename
6//! and line number of each node in the CFG.
7//!
8//! GCDA (gcov data) files are created when running the code program produced with `-Z profile` flag. For every edge in
9//! the CFG, the GCDA stores how many times this edge has been taken.
10//!
11//! Combining the statistics in GCDA and source information in GCNO, coverage tools can generate a branch coverage
12//! report.
13//!
14//! ## Examples
15//!
16//! GCNO and GCDA have a similar format, and are parsed using the same [`Reader`] class. The result is the [`Gcov`]
17//! structure. Complex projects will typically produce multiple GCNO and GCDA files. The statistics can be all merged
18//! into a single [`Graph`] class for analysis. Finally, an export-friendly [`Report`] structure can be derived from the
19//! `Graph`, to make it easy for creating a human-readable HTML report or generate data for third-party coverage
20//! collection services.
21//!
22//! The typical usage is like:
23//!
24//! ```rust
25//! extern crate cov;
26//! extern crate serde_json;
27//! use cov::{Gcov, Graph, Interner, SerializeWithInterner};
28//!
29//! # fn main() { run().unwrap(); }
30//! # fn run() -> cov::Result<()> {
31//! let mut interner = Interner::default();
32//! let mut graph = Graph::default();
33//!
34//! // merge the coverage statistics.
35//! // note: merge all gcno before gcda.
36//! graph.merge(Gcov::open("test-data/trivial.clang/x.gcno", &mut interner)?)?;
37//! graph.merge(Gcov::open("test-data/trivial.rustc/x.gcno", &mut interner)?)?;
38//!
39//! graph.merge(Gcov::open("test-data/trivial.clang/x.gcda", &mut interner)?)?;
40//! graph.merge(Gcov::open("test-data/trivial.rustc/x.gcda", &mut interner)?)?;
41//!
42//! // analyze the graph (if you skip this step, the report will be empty)
43//! graph.analyze();
44//!
45//! // produce the report.
46//! let report = graph.report();
47//!
48//! // serialize the report into json.
49//! println!("{}", serde_json::to_string_pretty(&report.with_interner(&interner))?);
50//! # Ok(()) }
51//! ```
52//!
53//! [cfg]: https://en.wikipedia.org/wiki/Control_flow_graph
54//! [`Reader`]: ./reader/struct.Reader.html
55//! [`Gcov`]: ./raw/struct.Gcov.html
56//! [`Graph`]: ./graph/struct.Graph.html
57//! [`Report`]: ./report/struct.Report.html
58
59#![recursion_limit = "128"] // needed for error_chain.
60
61#![cfg_attr(feature = "cargo-clippy", warn(warnings, clippy_pedantic))]
62#![cfg_attr(feature = "cargo-clippy", allow(missing_docs_in_private_items, use_debug, cast_possible_truncation))]
63
64#[macro_use]
65extern crate error_chain;
66#[macro_use]
67extern crate bitflags;
68#[macro_use]
69extern crate log;
70#[cfg(feature = "serde")]
71#[macro_use]
72extern crate serde;
73#[cfg(feature = "serde_json")]
74extern crate serde_json;
75extern crate byteorder;
76extern crate petgraph;
77extern crate fixedbitset;
78extern crate num_traits; // required for shawshank
79extern crate shawshank;
80
81#[macro_use]
82pub mod intern;
83#[cfg(feature = "serde")]
84pub mod deserializer;
85mod utils;
86pub mod error;
87pub mod raw;
88pub mod reader;
89pub mod graph;
90pub mod report;
91
92#[cfg(feature = "serde")]
93pub use deserializer::with_interner as deserializer_with_interner;
94pub use error::{ErrorKind, Result};
95pub use graph::Graph;
96pub use intern::{Interner, Symbol};
97#[cfg(feature = "serde")]
98pub use intern::SerializeWithInterner;
99pub use raw::Gcov;
100pub use report::Report;
101pub use utils::IntoStringLossy;