Skip to main content

luaur_repl_cli/functions/
coverage_callback.rs

1use core::ffi::{c_char, c_int, c_void, CStr};
2use std::ffi::CString;
3use std::io::Write;
4
5extern "C" {
6    fn fprintf(stream: *mut c_void, format: *const c_char, ...) -> c_int;
7}
8
9pub unsafe fn coverage_callback(
10    context: *mut c_void,
11    function: *const c_char,
12    linedefined: c_int,
13    depth: c_int,
14    hits: *const c_int,
15    size: usize,
16) {
17    if context.is_null() {
18        return;
19    }
20
21    let name = if depth == 0 {
22        "<main>".to_string()
23    } else if !function.is_null() {
24        let func_str = CStr::from_ptr(function).to_string_lossy();
25        format!("{}:{}", func_str, linedefined)
26    } else {
27        format!("<anonymous>:{}", linedefined)
28    };
29
30    let name_c = CString::new(name.clone()).unwrap();
31    fprintf(
32        context,
33        "FN:%d,%s\n\0".as_ptr() as *const c_char,
34        linedefined,
35        name_c.as_ptr(),
36    );
37
38    let hits_slice = core::slice::from_raw_parts(hits, size);
39
40    for i in 0..size {
41        if hits_slice[i] != -1 {
42            let name_c = CString::new(name.clone()).unwrap();
43            fprintf(
44                context,
45                "FNDA:%d,%s\n\0".as_ptr() as *const c_char,
46                hits_slice[i],
47                name_c.as_ptr(),
48            );
49            break;
50        }
51    }
52
53    for i in 0..size {
54        if hits_slice[i] != -1 {
55            fprintf(
56                context,
57                "DA:%d,%d\n\0".as_ptr() as *const c_char,
58                i as c_int,
59                hits_slice[i],
60            );
61        }
62    }
63}