Skip to content

Commit 8ef3d6d

Browse files
committed
ctest: add foreign fn tests
1 parent e634372 commit 8ef3d6d

File tree

18 files changed

+311
-70
lines changed

18 files changed

+311
-70
lines changed

ctest-next/src/ast/function.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ use crate::{Abi, BoxStr, Parameter};
66
#[derive(Debug, Clone)]
77
pub struct Fn {
88
pub(crate) public: bool,
9-
#[expect(unused)]
109
pub(crate) abi: Abi,
1110
pub(crate) ident: BoxStr,
1211
pub(crate) link_name: Option<BoxStr>,
13-
#[expect(unused)]
1412
pub(crate) parameters: Vec<Parameter>,
1513
#[expect(unused)]
1614
pub(crate) return_type: Option<syn::Type>,
15+
pub(crate) bare_fn_signature: BoxStr,
1716
}
1817

1918
impl Fn {

ctest-next/src/ast/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ mod structure;
77
mod type_alias;
88
mod union;
99

10+
use std::fmt;
11+
1012
pub use constant::Const;
1113
pub use field::Field;
1214
pub use function::Fn;
@@ -37,6 +39,16 @@ impl From<&str> for Abi {
3739
}
3840
}
3941

42+
impl fmt::Display for Abi {
43+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44+
match self {
45+
Abi::C => write!(f, "C"),
46+
Abi::Rust => write!(f, "Rust"),
47+
Abi::Other(s) => write!(f, "{s}"),
48+
}
49+
}
50+
}
51+
4052
/// Things that can appear directly inside of a module or scope.
4153
///
4254
/// This is not an exhaustive list and only contains variants directly useful

ctest-next/src/ffi_items.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::ops::Deref;
22

3+
use quote::ToTokens;
34
use syn::punctuated::Punctuated;
45
use syn::visit::Visit;
56

@@ -57,7 +58,6 @@ impl FfiItems {
5758
}
5859

5960
/// Return a list of all foreign functions found mapped by their ABI.
60-
#[cfg_attr(not(test), expect(unused))]
6161
pub(crate) fn foreign_functions(&self) -> &Vec<Fn> {
6262
&self.foreign_functions
6363
}
@@ -142,6 +142,7 @@ fn visit_foreign_item_fn(table: &mut FfiItems, i: &syn::ForeignItemFn, abi: &Abi
142142
syn::ReturnType::Type(_, ty) => Some(ty.deref().clone()),
143143
};
144144
let link_name = extract_single_link_name(&i.attrs);
145+
let bare_fn_signature = i.sig.to_token_stream().to_string().into_boxed_str();
145146

146147
table.foreign_functions.push(Fn {
147148
public,
@@ -150,6 +151,7 @@ fn visit_foreign_item_fn(table: &mut FfiItems, i: &syn::ForeignItemFn, abi: &Abi
150151
link_name,
151152
parameters,
152153
return_type,
154+
bare_fn_signature,
153155
});
154156
}
155157

ctest-next/src/generator.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ pub struct TestGenerator {
4141
pub(crate) skips: Vec<Skip>,
4242
verbose_skip: bool,
4343
pub(crate) volatile_items: Vec<VolatileItem>,
44-
array_arg: Option<ArrayArg>,
44+
pub(crate) array_arg: Option<ArrayArg>,
4545
skip_private: bool,
4646
pub(crate) skip_roundtrip: Option<SkipTest>,
4747
pub(crate) skip_signededness: Option<SkipTest>,
48+
pub(crate) skip_fn_ptrcheck: Option<SkipTest>,
4849
}
4950

5051
#[derive(Debug, Error)]
@@ -855,6 +856,21 @@ impl TestGenerator {
855856
self
856857
}
857858

859+
/// Configures whether tests for a function pointer's value are generated.
860+
///
861+
/// The closure is given a Rust FFI function and returns whether
862+
/// the test will be generated.
863+
///
864+
/// By default generated tests will ensure that the function pointer in C
865+
/// corresponds to the same function pointer in Rust. This can often
866+
/// uncover subtle symbol naming issues where a header file is referenced
867+
/// through the C identifier `foo` but the underlying symbol is mapped to
868+
/// something like `__foo_compat`.
869+
pub fn skip_fn_ptrcheck(&mut self, f: impl Fn(&str) -> bool + 'static) -> &mut Self {
870+
self.skip_fn_ptrcheck = Some(Box::new(f));
871+
self
872+
}
873+
858874
/// Generate the Rust and C testing files.
859875
///
860876
/// Returns the path to the generated file.

ctest-next/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type BoxStr = Box<str>;
3636
///
3737
/// This is necessary because `ctest` does not parse the header file, so it
3838
/// does not know which items are volatile.
39-
#[derive(Debug)]
39+
#[derive(Debug, Clone)]
4040
#[non_exhaustive]
4141
pub enum VolatileItemKind {
4242
/// A struct field.

0 commit comments

Comments
 (0)