Skip to content

Commit

Permalink
Add a way to specify that a function argument is an array in C
Browse files Browse the repository at this point in the history
  • Loading branch information
gnzlbg committed Mar 4, 2019
1 parent 147ae17 commit f551ca7
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ctest"
version = "0.2.12"
version = "0.2.13"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT/Apache-2.0"
readme = "README.md"
Expand Down
34 changes: 34 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ pub struct TestGenerator {
cfg: Vec<(String, Option<String>)>,
verbose_skip: bool,
volatile_item: Box<Fn(VolatileItemKind) -> bool>,
array_arg: Box<Fn(&str, usize) -> bool>,
skip_fn: Box<Fn(&str) -> bool>,
skip_fn_ptrcheck: Box<Fn(&str) -> bool>,
skip_static: Box<Fn(&str) -> bool>,
Expand Down Expand Up @@ -147,6 +148,7 @@ impl TestGenerator {
cfg: Vec::new(),
verbose_skip: false,
volatile_item: Box::new(|_| false),
array_arg: Box::new(|_,_| false),
skip_fn: Box::new(|_| false),
skip_fn_ptrcheck: Box::new(|_| false),
skip_static: Box::new(|_| false),
Expand Down Expand Up @@ -451,6 +453,31 @@ impl TestGenerator {
self
}

/// Is argument of function an array?
///
/// The closure denotes whether particular argument of a function is an array.
///
/// # Examples
///
/// ```no_run
/// use ctest::{TestGenerator};
///
/// let mut cfg = TestGenerator::new();
/// cfg.array_arg(|i, n| {
/// match (i, n) {
/// ("foo", 0) => true,
/// _ => false,
/// }});
/// ```
pub fn array_arg<F>(&mut self, f: F) -> &mut Self
where
F: Fn(&str, usize) -> bool + 'static,
{
self.array_arg = Box::new(f);
self
}


/// Configures how Rust `const`s names are translated to C.
///
/// The closure is given a Rust `const` name. The name of the corresponding
Expand Down Expand Up @@ -1512,6 +1539,13 @@ impl<'a> Generator<'a> {
)) {
arg = format!("volatile {}", arg);
}
if (self.opts.array_arg)(name, idx) {
if let Some(last_ptr) = arg.rfind("*") {
arg = format!("{}", &arg[..last_ptr]);
} else {
panic!("C FFI decl `{}` contains array argument", name);
}
}
arg
})
.map(|s| {
Expand Down
9 changes: 9 additions & 0 deletions testcrate/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fn main() {
t => t.to_string(),
})
.volatile_item(t1_volatile)
.array_arg(t1_arrays)
.generate("src/t1.rs", "t1gen.rs");
ctest::TestGenerator::new()
.header("t2.h")
Expand All @@ -50,6 +51,7 @@ fn main() {
t => t.to_string(),
})
.volatile_item(t1_volatile)
.array_arg(t1_arrays)
.generate("src/t1.rs", "t1gen_cxx.rs");
ctest::TestGenerator::new()
.header("t2.h")
Expand All @@ -76,3 +78,10 @@ fn t1_volatile(i: ctest::VolatileItemKind) -> bool {
_ => false,
}
}

fn t1_arrays(n: &str, i: usize) -> bool {
match n {
"T1r" | "T1s" | "T1t" | "T1v" if i == 0 => true,
_ => false,
}
}
5 changes: 5 additions & 0 deletions testcrate/src/t1.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ void T1j(const int32_t b[4]) {}
void T1o(int32_t (*a)[4]) {}
void T1p(int32_t (*const a)[4]) {}

void T1r(Arr a) {}
void T1s(const Arr a) {}
void T1t(Arr* a) {}
void T1v(const Arr* a) {}

unsigned T1static = 3;

const uint8_t T1_static_u8 = 42;
Expand Down
7 changes: 7 additions & 0 deletions testcrate/src/t1.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ void T1j(const int32_t b[4]);
void T1o(int32_t (*a)[4]);
void T1p(int32_t (*const a)[4]);

typedef int32_t (Arr)[4];

void T1r(Arr a);
void T1s(const Arr a);
void T1t(Arr* a);
void T1v(const Arr* a);

#define T1C 4

extern uint32_t T1static;
Expand Down
8 changes: 8 additions & 0 deletions testcrate/src/t1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ i! {

const NOT_PRESENT: u32 = 5;

pub type Arr = [i32; 4];

extern "C" {
pub fn T1a();
pub fn T1b() -> *mut c_void;
Expand All @@ -73,6 +75,12 @@ extern "C" {
pub fn T1o(a: *mut *mut [i32; 4]);
pub fn T1p(a: *const *const [i32; 4]) -> !;

pub fn T1r(a: *mut Arr);
pub fn T1s(a: *const Arr) -> !;
pub fn T1t(a: *mut *mut Arr);
pub fn T1v(a: *const *const Arr) -> !;


pub static T1static: c_uint;
}

Expand Down

0 comments on commit f551ca7

Please sign in to comment.