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