macro_rules! botan_ffi_functions {
(
$(
$(#[cfg($cfg:ident)])?
pub fn $name:ident ( $($arg:ident : $ty:ty),* $(,)? ) $( -> $ret:ty $( = $dflt:expr )? )? ;
)*
) => {
$(
__botan_ffi_function! {
@cfg [ $($cfg)? ]
@dflt [ $( $( $dflt )? )? ]
pub fn $name ( $($arg : $ty),* ) $( -> $ret )? ;
}
)*
};
}
macro_rules! __botan_ffi_function {
(
@cfg [ $($cfg:ident)? ]
@dflt [ $($dflt:expr)? ]
pub fn $name:ident ( $($arg:ident : $ty:ty),* ) $( -> $ret:ty )? ;
) => {
#[cfg(not(feature = "dynamic-loading"))]
$( #[cfg($cfg)] )?
unsafe extern "C" {
pub fn $name ( $($arg : $ty),* ) $( -> $ret )? ;
}
__botan_ffi_stub! {
@cfg [ $($cfg)? ]
@dflt [ $($dflt)? ]
pub fn $name ( $($arg : $ty),* ) $( -> $ret )? ;
}
#[cfg(feature = "dynamic-loading")]
#[allow(non_snake_case, clippy::missing_safety_doc)]
pub unsafe extern "C" fn $name ( $($arg : $ty),* ) $( -> $ret )? {
static SYM: $crate::loader::Symbol<unsafe extern "C" fn($($ty),*) $( -> $ret )?> =
$crate::loader::Symbol::new(concat!(stringify!($name), "\0"));
match unsafe { SYM.get() } {
Ok(f) => unsafe { f($($arg),*) },
Err($crate::loader::Unavailable::Function) => {
__botan_unavailable_value!( $($dflt)? )
}
Err($crate::loader::Unavailable::Library) => {
__botan_not_loaded_value!( $($dflt)? )
}
}
}
};
}
macro_rules! __botan_ffi_stub {
(
@cfg [ ]
$($rest:tt)*
) => {};
(
@cfg [ $cfg:ident ]
@dflt [ $($dflt:expr)? ]
pub fn $name:ident ( $($arg:ident : $ty:ty),* ) $( -> $ret:ty )? ;
) => {
#[cfg(all(not(feature = "dynamic-loading"), not($cfg)))]
#[allow(unused_variables, non_snake_case, clippy::missing_safety_doc)]
#[doc = concat!("Stub for `", stringify!($name), "`, which is not provided by the version of Botan detected at build time (requires `", stringify!($cfg), "`).")]
pub unsafe extern "C" fn $name ( $($arg : $ty),* ) $( -> $ret )? {
__botan_unavailable_value!( $($dflt)? )
}
};
}
macro_rules! __botan_unavailable_value {
() => {
$crate::BOTAN_FFI_ERROR_FUNCTION_NOT_AVAILABLE
};
($dflt:expr) => {
$dflt
};
}
macro_rules! __botan_not_loaded_value {
() => {
$crate::BOTAN_FFI_ERROR_LIBRARY_NOT_LOADED
};
($dflt:expr) => {
$dflt
};
}