syd 3.52.0

rock-solid application kernel
Documentation
//
// Syd: rock-solid application kernel
// src/kcov/api.rs: KCOV API utilities
//
// Copyright (c) 2025, 2026 Ali Polatel <alip@chesswob.org>
// SPDX-License-Identifier: GPL-3.0

// SAFETY: This module has been liberated from unsafe code!
#![forbid(unsafe_code)]

use nix::errno::Errno;

/// Constant FNV-1a 64-bit; fast, deterministic site IDs.
pub const fn kcov_hash64(s: &str) -> u64 {
    let bytes = s.as_bytes();
    let mut h: u64 = 0xcbf29ce484222325;
    let mut i: usize = 0;
    while i < bytes.len() {
        h ^= bytes[i] as u64;
        h = h.wrapping_mul(0x100000001b3);
        i += 1;
    }
    h
}

/// Record a PC edge; no-ops if not enabled (kcov handles TLS/noop)
pub fn record_pc(pc: u64) -> Result<(), Errno> {
    // Route to the single KCOV manager owned by glue.
    crate::kcov::abi::record_pc(pc)
}

//
// API macros for coverage:
// Gated by `kcov` feature and no-op when disabled.
//

/// Emit a lightweight edge at the current callsite using a stable compile-time site ID.
///
/// No-op when `kcov` feature is disabled.
#[macro_export]
macro_rules! kcov_edge {
    // Auto-site: use file:line:col
    () => {{
        const __KCOV_SITE: u64 = $crate::kcov::api::kcov_hash64(concat!(file!(), ":", line!()));
        let _ = $crate::kcov::api::record_pc(__KCOV_SITE);
    }};
    // User-specified site (any expression -> u64).
    ($site:expr) => {{
        let _ = $crate::kcov::api::record_pc(($site) as u64);
    }};
}

/// Emit an edge tagged by a human-readable string hashed at compile time.
///
/// No-op when `kcov` feature is disabled.
#[macro_export]
macro_rules! kcov_edge_site {
    // Compile-time string -> Hashed site
    ($s:literal) => {{
        const __KCOV_SITE: u64 = $crate::kcov::api::kcov_hash64($s);
        let _ = $crate::kcov::api::record_pc(__KCOV_SITE);
    }};
}

/// Record a comparison with automatic site ID.
///
/// No-op when `kcov` feature is disabled.
#[macro_export]
macro_rules! kcov_cmp {
    // Infer ip from callsite.
    ($sz:expr, $isconst:expr, $a:expr, $b:expr) => {{
        const __KCOV_SITE: u64 = $crate::kcov::api::kcov_hash64(concat!(file!(), ":", line!()));
        let _ = $crate::kcov::api::record_cmp(
            ($sz) as u8,
            ($isconst),
            ($a) as u64,
            ($b) as u64,
            __KCOV_SITE,
        );
    }};
    // Explicit site id (u64 or anything -> u64).
    ($sz:expr, $isconst:expr, $a:expr, $b:expr, $site:expr) => {{
        let _ = $crate::kcov::api::record_cmp(
            ($sz) as u8,
            ($isconst),
            ($a) as u64,
            ($b) as u64,
            ($site) as u64,
        );
    }};
}

/// Record a comparison tagged by a human-readable string hashed at compile time.
///
/// No-op when `kcov` feature is disabled.
#[macro_export]
macro_rules! kcov_cmp_site {
    // compile-time string site
    ($sz:expr, $isconst:expr, $a:expr, $b:expr, $s:literal) => {{
        const __KCOV_SITE: u64 = $crate::kcov::api::kcov_hash64($s);
        let _ = $crate::kcov::api::record_cmp(
            ($sz) as u8,
            ($isconst),
            ($a) as u64,
            ($b) as u64,
            __KCOV_SITE,
        );
    }};
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_kcov_hash64_empty_1() {
        // FNV-1a initial value for empty string.
        let h = kcov_hash64("");
        assert_eq!(h, 0xcbf29ce484222325u64);
    }

    #[test]
    fn test_kcov_hash64_deterministic_1() {
        assert_eq!(kcov_hash64("foo"), kcov_hash64("foo"));
    }

    #[test]
    fn test_kcov_hash64_different_inputs_1() {
        assert_ne!(kcov_hash64("foo"), kcov_hash64("bar"));
    }

    #[test]
    fn test_kcov_hash64_different_inputs_2() {
        assert_ne!(kcov_hash64("a"), kcov_hash64("b"));
    }

    #[test]
    fn test_kcov_hash64_const_eval_1() {
        const H: u64 = kcov_hash64("syd");
        assert_ne!(H, 0);
    }

    #[test]
    fn test_kcov_hash64_known_value_1() {
        // FNV-1a of "a": 0xe40c292c
        // 64-bit: 0xaf63dc4c8601ec8c (known reference value)
        let h = kcov_hash64("a");
        assert_eq!(h, 0xaf63dc4c8601ec8cu64);
    }
}