#![allow(renamed_and_removed_lints, unused_doc_comments)]
use raw::{Ident, Type, Version};
use std::{fmt, io};
use std::error::Error as StdError;
use std::path::PathBuf;
use std::result::Result as StdResult;
error_chain! {
foreign_links {
Io(io::Error) ;
Json(::serde_json::Error) #[cfg(feature="serde_json")] ;
}
errors {
UnknownFileType(magic: u32) {
description("unknown file type")
display("unknown file type, magic 0x{:08x} not recognized", magic)
}
VersionMismatch(expected: Version, actual: Version) {
description("version mismatch")
display("version mismatch, existing graph has \"{}\", incoming file has \"{}\"", expected, actual)
}
Eof {
description("encountered EOF record")
}
UnknownTag(tag: u32) {
description("unknown record")
display("unknown record, tag 0x{:08x} not recognized", tag)
}
UnsupportedAttr(kind: &'static str, raw_flag: u32) {
description("unsupported flags")
display("unsupported {} flags 0x{:x}", kind, raw_flag)
}
UnsupportedVersion(version: u32) {
description("unsupported gcov version")
display("unsupported gcov version 0x{:08x}", version)
}
MissingFunction(file_checksum: u32, ident: Ident) {
description("missing function")
display("function from *.gcda cannot be found in the *.gcno (checksum: {}, ident: {})", file_checksum, ident)
}
RecordWithoutFunction {
description("encountered a record without the corresponding function")
}
CountsMismatch(kind: &'static str, ty: Type, expected: usize, actual: usize) {
description("counts mismatch")
display("{0} counts mismatch on *.{3}, expecting {1} {0}, received {2} {0}", kind, expected, actual, ty)
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Location {
None,
Cursor(u64),
RecordIndex(usize),
File(PathBuf),
}
impl Location {
pub fn wrap<T, E: Into<Error>, F: FnOnce() -> StdResult<T, E>>(self, f: F) -> Result<T> {
f().map_err(|e| self.wrap_error(e))
}
pub fn wrap_error<E: Into<Error>>(self, e: E) -> Error {
let mut error = e.into();
if self != Location::None {
let cause = Box::new(AtError {
location: self,
cause: error.1.next_error,
});
error.1.next_error = Some(cause);
}
error
}
}
#[derive(Debug)]
struct AtError {
location: Location,
cause: Option<Box<StdError + Send + 'static>>,
}
impl fmt::Display for AtError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.location {
Location::Cursor(cursor) => write!(fmt, "reading at file position {0} (0x{0:x})", cursor),
Location::RecordIndex(index) => write!(fmt, "parsing record index #{}", index),
Location::File(ref path) => write!(fmt, "parsing file {}", path.display()),
Location::None => write!(fmt, "nothing"),
}
}
}
impl StdError for AtError {
fn description(&self) -> &str {
"<error context>"
}
fn cause(&self) -> Option<&StdError> {
self.cause.as_ref().map(|e| -> &StdError { &**e })
}
}
pub trait IsEof {
fn is_eof(&self) -> bool;
}
impl IsEof for ErrorKind {
fn is_eof(&self) -> bool {
match *self {
ErrorKind::Io(ref e) => e.is_eof(),
ErrorKind::Eof => true,
_ => false,
}
}
}
impl IsEof for Error {
fn is_eof(&self) -> bool {
self.kind().is_eof()
}
}
impl IsEof for io::Error {
fn is_eof(&self) -> bool {
self.kind() == io::ErrorKind::UnexpectedEof
}
}