summaryrefslogtreecommitdiff
path: root/lib/coverage/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/coverage/src/lib.rs')
-rw-r--r--lib/coverage/src/lib.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/lib/coverage/src/lib.rs b/lib/coverage/src/lib.rs
new file mode 100644
index 00000000..003f8b88
--- /dev/null
+++ b/lib/coverage/src/lib.rs
@@ -0,0 +1,132 @@
+extern crate lazy_static;
+use lazy_static::lazy_static;
+
+use std::collections::HashSet;
+use std::ffi::{CStr, CString};
+use std::fs::{OpenOptions, File};
+use std::io::Write;
+use std::os::raw::{c_char, c_int};
+use std::sync::Mutex;
+
+#[derive(Eq, PartialEq, Hash)]
+struct Span {
+ sail_file: CString,
+ line1: i32,
+ char1: i32,
+ line2: i32,
+ char2: i32,
+}
+
+lazy_static! {
+ static ref BRANCHES: Mutex<HashSet<Span>> = Mutex::new(HashSet::new());
+ static ref FUNCTIONS: Mutex<HashSet<Span>> = Mutex::new(HashSet::new());
+}
+
+fn function_entry(_function_name: &CStr, span: Span) {
+ FUNCTIONS.lock().unwrap().insert(span);
+}
+
+fn branch_taken(_branch_id: i32, span: Span) {
+ BRANCHES.lock().unwrap().insert(span);
+}
+
+fn branch_reached(_branch_id: i32, _span: Span) {
+ ()
+}
+
+fn write_locations(file: &mut File, kind: char, spans: &Mutex<HashSet<Span>>) -> bool {
+ for span in spans.lock().unwrap().iter() {
+ let res = write!(
+ file,
+ "{} \"{}\", {}, {}, {}, {}\n",
+ kind,
+ span.sail_file.to_string_lossy(),
+ span.line1,
+ span.char1,
+ span.line2,
+ span.char2,
+ );
+ if res.is_err() {
+ return false;
+ }
+ };
+ true
+}
+
+#[no_mangle]
+pub extern "C" fn sail_coverage_exit() -> c_int {
+ if let Ok(mut file) = OpenOptions::new().create(true).append(true).open("sail_coverage") {
+ if !write_locations(&mut file, 'B', &BRANCHES) {
+ return 1
+ }
+ if !write_locations(&mut file, 'F', &FUNCTIONS) {
+ return 1
+ }
+ 0
+ } else {
+ 1
+ }
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn sail_function_entry(
+ function_name: *const c_char,
+ sail_file: *const c_char,
+ l1: c_int,
+ c1: c_int,
+ l2: c_int,
+ c2: c_int,
+) {
+ function_entry(
+ CStr::from_ptr(function_name),
+ Span {
+ sail_file: CStr::from_ptr(sail_file).into(),
+ line1: l1 as i32,
+ char1: c1 as i32,
+ line2: l2 as i32,
+ char2: c2 as i32,
+ },
+ )
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn sail_branch_taken(
+ branch_id: c_int,
+ sail_file: *const c_char,
+ l1: c_int,
+ c1: c_int,
+ l2: c_int,
+ c2: c_int,
+) {
+ branch_taken(
+ branch_id as i32,
+ Span {
+ sail_file: CStr::from_ptr(sail_file).into(),
+ line1: l1 as i32,
+ char1: c1 as i32,
+ line2: l2 as i32,
+ char2: c2 as i32,
+ },
+ )
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn sail_branch_reached(
+ branch_id: c_int,
+ sail_file: *const c_char,
+ l1: c_int,
+ c1: c_int,
+ l2: c_int,
+ c2: c_int,
+) {
+ branch_reached(
+ branch_id as i32,
+ Span {
+ sail_file: CStr::from_ptr(sail_file).into(),
+ line1: l1 as i32,
+ char1: c1 as i32,
+ line2: l2 as i32,
+ char2: c2 as i32,
+ },
+ )
+}