Skip to content

Commit

Permalink
Improve support for arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
gnzlbg committed Mar 4, 2019
1 parent cc5690a commit fb76cbc
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 11 deletions.
32 changes: 30 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,23 @@ impl<'a> Generator<'a> {
}
arg
})
.map(|s| {
if let Some(i) = s.rfind(']') {
let c = s.chars().filter(|&c| c == '*').count();
if c == 0 {
return s;
}
let postfix_idx = s.find('[').unwrap();
let postfix = &s[postfix_idx..=i];
let prefix = &s[..postfix_idx];
let pointers = &s[i + 1..];
let has_const = pointers.contains("const");
let pointers = pointers.replace("const *", "* const");
let prefix = prefix.replacen("const", "", if has_const { 1 } else { 0 });
return format!("{} ({}) {}", prefix, pointers, postfix);
}
return s;
})
.collect::<Vec<_>>()
.join(", ")
+ if variadic { ", ..." } else { "" }
Expand Down Expand Up @@ -1750,8 +1767,10 @@ impl<'a> Generator<'a> {
ast::TyKind::Ptr(..) => {
format!("{} {}*", self.ty2name(&t.ty, rust), modifier)
}
ast::TyKind::Array(ref t, _) => {
format!("{}{}*", modifier, self.ty2name(t, rust))
ast::TyKind::Array(ref t, ref e) => {
let len = self.expr2str(e);
let ty = self.ty2name(t, rust);
format!("{} {} [{}]", modifier, ty, len)
}
_ => format!("{}{}*", modifier, self.ty2name(&t.ty, rust)),
}
Expand Down Expand Up @@ -2027,6 +2046,15 @@ impl<'a, 'v> Visitor<'v> for Generator<'a> {
match i.node {
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
self.assert_no_generics(i.ident, generics);
for ref arg in &decl.inputs {
if let ast::TyKind::Array(_, _) = arg.ty.node {
panic!(
"Foreing Function decl `{}` uses array in C FFI",
&i.ident.to_string()
);
}
}

let (ret, args, variadic) = self.decl2rust(decl);
let c_name = attr::first_attr_value_str_by_name(&i.attrs, "link_name")
.map(|i| i.to_string());
Expand Down
10 changes: 7 additions & 3 deletions testcrate/src/t1.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <stdint.h>
#include "t1.h"

void T1a(void) {}
Expand All @@ -7,10 +8,13 @@ void* T1c(void* a) { return NULL; }
int32_t T1d(unsigned a ) { return 0; }
void T1e(unsigned a, const struct T1Bar* b) { }
void T1f(void) {}
void T1g(const int32_t a[4]) {}
void T1h(const int32_t a[4]) {}
void T1g(int32_t* a) {}
void T1h(const int32_t* b) {}
void T1i(int32_t a[4]) {}
void T1j(int32_t a[4]) {}
void T1j(const int32_t b[4]) {}
void T1o(int32_t (*a)[4]) {}
void T1p(int32_t (*const a)[4]) {}

unsigned T1static = 3;

const uint8_t T1_static_u8 = 42;
Expand Down
8 changes: 5 additions & 3 deletions testcrate/src/t1.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ void* T1c(void*);
int32_t T1d(unsigned);
void T1e(unsigned, const struct T1Bar*);
void T1f(void);
void T1g(const int32_t a[4]);
void T1h(const int32_t a[4]);
void T1g(int32_t* a);
void T1h(const int32_t* b);
void T1i(int32_t a[4]);
void T1j(int32_t a[4]);
void T1j(const int32_t b[4]);
void T1o(int32_t (*a)[4]);
void T1p(int32_t (*const a)[4]);

#define T1C 4

Expand Down
8 changes: 5 additions & 3 deletions testcrate/src/t1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ extern "C" {
#[link_name = "T1f"]
pub fn f() -> ();

pub fn T1g(a: *const [i32; 4]);
pub fn T1h(a: &[i32; 4]);
pub fn T1g(a: *mut [i32; 4]);
pub fn T1h(a: *const [i32; 4]) -> !;
pub fn T1i(a: *mut [i32; 4]);
pub fn T1j(a: &mut [i32; 4]) -> !;
pub fn T1j(a: *const [i32; 4]) -> !;
pub fn T1o(a: *mut *mut [i32; 4]);
pub fn T1p(a: *const *const [i32; 4]) -> !;

pub static T1static: c_uint;
}
Expand Down

0 comments on commit fb76cbc

Please sign in to comment.