Format with rustfmt-nightly

This commit is contained in:
Ryan Hunt 2017-11-18 21:44:33 -05:00
parent ce60054f8d
commit 58d3178dc5
34 changed files with 1222 additions and 1036 deletions

View File

@ -8,7 +8,7 @@ use std::path;
use std::fs;
use bindgen::config::{Config, Language};
use bindgen::ir::{Constant, ItemContainer, Function, Static};
use bindgen::ir::{Constant, Function, ItemContainer, Static};
use bindgen::writer::{Source, SourceWriter};
/// A bindings header that can be written.
@ -21,11 +21,13 @@ pub struct Bindings {
}
impl Bindings {
pub(crate) fn new(config: Config,
constants: Vec<Constant>,
globals: Vec<Static>,
items: Vec<ItemContainer>,
functions: Vec<Function>) -> Bindings {
pub(crate) fn new(
config: Config,
constants: Vec<Constant>,
globals: Vec<Static>,
items: Vec<ItemContainer>,
functions: Vec<Function>,
) -> Bindings {
Bindings {
config: config,
globals: globals,
@ -60,8 +62,11 @@ impl Bindings {
}
if self.config.include_version {
out.new_line_if_not_start();
write!(out, "/* Generated with cbindgen:{} */",
::bindgen::config::VERSION);
write!(
out,
"/* Generated with cbindgen:{} */",
::bindgen::config::VERSION
);
out.new_line();
}
if let Some(ref f) = self.config.autogen_warning {
@ -96,7 +101,11 @@ impl Bindings {
}
for item in &self.items {
if item.deref().annotations().bool("no-export").unwrap_or(false) {
if item.deref()
.annotations()
.bool("no-export")
.unwrap_or(false)
{
continue;
}

View File

@ -33,98 +33,104 @@ impl Builder {
#[allow(unused)]
pub fn with_header<S: AsRef<str>>(mut self, header: S) -> Builder {
self.config.header = Some(String::from(header.as_ref()));
self
self.config.header = Some(String::from(header.as_ref()));
self
}
#[allow(unused)]
pub fn with_trailer<S: AsRef<str>>(mut self, trailer: S) -> Builder {
self.config.trailer = Some(String::from(trailer.as_ref()));
self
self.config.trailer = Some(String::from(trailer.as_ref()));
self
}
#[allow(unused)]
pub fn with_include_guard<S: AsRef<str>>(mut self, include_guard: S) -> Builder {
self.config.include_guard = Some(String::from(include_guard.as_ref()));
self
self.config.include_guard = Some(String::from(include_guard.as_ref()));
self
}
#[allow(unused)]
pub fn with_autogen_warning<S: AsRef<str>>(mut self, autogen_warning: S) -> Builder {
self.config.autogen_warning = Some(String::from(autogen_warning.as_ref()));
self
self.config.autogen_warning = Some(String::from(autogen_warning.as_ref()));
self
}
#[allow(unused)]
pub fn with_include_version(mut self, include_version: bool) -> Builder {
self.config.include_version = include_version;
self
self.config.include_version = include_version;
self
}
#[allow(unused)]
pub fn with_namespace<S: AsRef<str>>(mut self, namespace: S) -> Builder {
self.config.namespace = Some(String::from(namespace.as_ref()));
self
self.config.namespace = Some(String::from(namespace.as_ref()));
self
}
#[allow(unused)]
pub fn with_namespaces<S: AsRef<str>>(mut self, namespaces: &[S]) -> Builder {
self.config.namespaces = Some(namespaces.iter().map(|x| String::from(x.as_ref())).collect());
self
self.config.namespaces = Some(
namespaces
.iter()
.map(|x| String::from(x.as_ref()))
.collect(),
);
self
}
#[allow(unused)]
pub fn with_braces(mut self, braces: Braces) -> Builder {
self.config.braces = braces;
self
self.config.braces = braces;
self
}
#[allow(unused)]
pub fn with_line_length(mut self, line_length: usize) -> Builder {
self.config.line_length = line_length;
self
self.config.line_length = line_length;
self
}
#[allow(unused)]
pub fn with_tab_width(mut self, tab_width: usize) -> Builder {
self.config.tab_width = tab_width;
self
self.config.tab_width = tab_width;
self
}
#[allow(unused)]
pub fn with_language(mut self, language: Language) -> Builder {
self.config.language = language;
self
self.config.language = language;
self
}
#[allow(unused)]
pub fn with_parse_deps(mut self, parse_deps: bool) -> Builder {
self.config.parse.parse_deps = parse_deps;
self
self.config.parse.parse_deps = parse_deps;
self
}
#[allow(unused)]
pub fn with_parse_include<S: AsRef<str>>(mut self, include: &[S]) -> Builder {
self.config.parse.include = Some(include.iter().map(|x| String::from(x.as_ref())).collect());
self
self.config.parse.include =
Some(include.iter().map(|x| String::from(x.as_ref())).collect());
self
}
#[allow(unused)]
pub fn with_parse_exclude<S: AsRef<str>>(mut self, exclude: &[S]) -> Builder {
self.config.parse.exclude = exclude.iter().map(|x| String::from(x.as_ref())).collect();
self
self.config.parse.exclude = exclude.iter().map(|x| String::from(x.as_ref())).collect();
self
}
#[allow(unused)]
pub fn with_parse_expand<S: AsRef<str>>(mut self, expand: &[S]) -> Builder {
self.config.parse.expand = expand.iter().map(|x| String::from(x.as_ref())).collect();
self
self.config.parse.expand = expand.iter().map(|x| String::from(x.as_ref())).collect();
self
}
#[allow(unused)]
pub fn with_documentation(mut self, documentation: bool) -> Builder {
self.config.documentation = documentation;
self
self.config.documentation = documentation;
self
}
#[allow(unused)]
@ -154,15 +160,17 @@ impl Builder {
}
#[allow(unused)]
pub fn with_crate_and_name<P: AsRef<path::Path>,
S: AsRef<str>>(mut self,
lib_dir: P,
binding_lib_name: S) -> Builder
{
pub fn with_crate_and_name<P: AsRef<path::Path>, S: AsRef<str>>(
mut self,
lib_dir: P,
binding_lib_name: S,
) -> Builder {
debug_assert!(self.lib.is_none());
debug_assert!(self.lib_cargo.is_none());
self.lib = Some((path::PathBuf::from(lib_dir.as_ref()),
Some(String::from(binding_lib_name.as_ref()))));
self.lib = Some((
path::PathBuf::from(lib_dir.as_ref()),
Some(String::from(binding_lib_name.as_ref())),
));
self
}
@ -187,36 +195,42 @@ impl Builder {
if let Some((lib_dir, binding_lib_name)) = self.lib.clone() {
let cargo = if let Some(binding_lib_name) = binding_lib_name {
Cargo::load(&lib_dir,
Some(&binding_lib_name),
self.config.parse.parse_deps)?
Cargo::load(
&lib_dir,
Some(&binding_lib_name),
self.config.parse.parse_deps,
)?
} else {
Cargo::load(&lib_dir,
None,
self.config.parse.parse_deps)?
Cargo::load(&lib_dir, None, self.config.parse.parse_deps)?
};
result.extend_with(&parser::parse_lib(cargo,
self.config.parse.parse_deps,
&self.config.parse.include,
&self.config.parse.exclude,
&self.config.parse.expand)?);
result.extend_with(&parser::parse_lib(
cargo,
self.config.parse.parse_deps,
&self.config.parse.include,
&self.config.parse.exclude,
&self.config.parse.expand,
)?);
} else if let Some(cargo) = self.lib_cargo.clone() {
result.extend_with(&parser::parse_lib(cargo,
self.config.parse.parse_deps,
&self.config.parse.include,
&self.config.parse.exclude,
&self.config.parse.expand)?);
result.extend_with(&parser::parse_lib(
cargo,
self.config.parse.parse_deps,
&self.config.parse.include,
&self.config.parse.exclude,
&self.config.parse.expand,
)?);
}
Library::new(self.config,
result.constants,
result.globals,
result.enums,
result.structs,
result.unions,
result.opaque_items,
result.typedefs,
result.functions).generate()
Library::new(
self.config,
result.constants,
result.globals,
result.enums,
result.structs,
result.unions,
result.opaque_items,
result.typedefs,
result.functions,
).generate()
}
}

View File

@ -36,9 +36,11 @@ impl Cargo {
/// Gather metadata from cargo for a specific library and binding crate
/// name. If dependency finding isn't needed then Cargo.lock files don't
/// need to be parsed.
pub(crate) fn load(crate_dir: &Path,
binding_crate_name: Option<&str>,
use_cargo_lock: bool) -> Result<Cargo, String> {
pub(crate) fn load(
crate_dir: &Path,
binding_crate_name: Option<&str>,
use_cargo_lock: bool,
) -> Result<Cargo, String> {
let toml_path = crate_dir.join("Cargo.toml");
let lock_path = crate_dir.join("Cargo.lock");
@ -53,15 +55,19 @@ impl Cargo {
} else {
None
};
let metadata = cargo_metadata::metadata(&toml_path)
.map_err(|_| format!("couldn't execute `cargo metadata` with manifest {:?}.", toml_path))?;
let metadata = cargo_metadata::metadata(&toml_path).map_err(|_| {
format!(
"couldn't execute `cargo metadata` with manifest {:?}.",
toml_path
)
})?;
// Use the specified binding crate name or infer it from the manifest
let manifest = cargo_toml::manifest(&toml_path)
.map_err(|_| format!("couldn't load {:?}.", toml_path))?;
.map_err(|_| format!("couldn't load {:?}.", toml_path))?;
let binding_crate_name = binding_crate_name.map_or(manifest.package.name.clone(),
|x| x.to_owned());
let binding_crate_name =
binding_crate_name.map_or(manifest.package.name.clone(), |x| x.to_owned());
Ok(Cargo {
manifest_path: toml_path,
@ -95,7 +101,11 @@ impl Cargo {
/// Finds the package reference for a dependency of a crate using
/// `Cargo.lock`.
pub(crate) fn find_dep_ref(&self, package: &PackageRef, dependency_name: &str) -> Option<PackageRef> {
pub(crate) fn find_dep_ref(
&self,
package: &PackageRef,
dependency_name: &str,
) -> Option<PackageRef> {
if self.lock.is_none() {
return None;
}
@ -149,10 +159,10 @@ impl Cargo {
#[allow(unused)]
pub(crate) fn find_crate_dir(&self, package: &PackageRef) -> Option<PathBuf> {
for meta_package in &self.metadata.packages {
if meta_package.name == package.name &&
meta_package.version == package.version {
return Path::new(&meta_package.manifest_path).parent()
.map(|x| x.to_owned());
if meta_package.name == package.name && meta_package.version == package.version {
return Path::new(&meta_package.manifest_path)
.parent()
.map(|x| x.to_owned());
}
}
None
@ -166,13 +176,12 @@ impl Cargo {
let kind_cdylib = String::from("cdylib");
for meta_package in &self.metadata.packages {
if meta_package.name == package.name &&
meta_package.version == package.version {
if meta_package.name == package.name && meta_package.version == package.version {
for target in &meta_package.targets {
if target.kind.contains(&kind_lib) ||
target.kind.contains(&kind_staticlib) ||
target.kind.contains(&kind_rlib) ||
target.kind.contains(&kind_cdylib) {
if target.kind.contains(&kind_lib) || target.kind.contains(&kind_staticlib)
|| target.kind.contains(&kind_rlib)
|| target.kind.contains(&kind_cdylib)
{
return Some(PathBuf::from(&target.src_path));
}
}

View File

@ -12,9 +12,7 @@ use self::tempdir::TempDir;
/// Use rustc to expand and pretty print the crate into a single file,
/// removing any macros in the process.
pub fn expand(manifest_path: &Path,
crate_name: &str,
version: &str) -> Result<String, String> {
pub fn expand(manifest_path: &Path, crate_name: &str, version: &str) -> Result<String, String> {
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
let run = |target_dir: &Path| {
let mut cmd = Command::new(cargo);

View File

@ -12,7 +12,7 @@
use std::collections::HashMap;
use std::env;
use std::process::Command;
use std::str::{from_utf8, Utf8Error};
use std::str::{Utf8Error, from_utf8};
use std::io;
use std::path::Path;

View File

@ -31,7 +31,7 @@ struct CDecl {
type_qualifers: String,
type_name: String,
type_generic_args: Vec<Type>,
declarators: Vec<CDeclarator>
declarators: Vec<CDeclarator>,
}
impl CDecl {
@ -56,8 +56,14 @@ impl CDecl {
}
fn build_func(&mut self, f: &Function, layout_vertical: bool) {
let args = f.args.iter().map(|&(ref arg_name, ref arg_ty)| (Some(arg_name.clone()), CDecl::from_type(arg_ty))).collect();
self.declarators.push(CDeclarator::Func(args, layout_vertical));
let args = f.args
.iter()
.map(|&(ref arg_name, ref arg_ty)| {
(Some(arg_name.clone()), CDecl::from_type(arg_ty))
})
.collect();
self.declarators
.push(CDeclarator::Func(args, layout_vertical));
self.build_type(&f.ret, false);
}
@ -84,7 +90,7 @@ impl CDecl {
self.type_name = p.to_string();
}
&Type::ConstPtr(ref t) => {
&Type::ConstPtr(ref t) => {
self.declarators.push(CDeclarator::Ptr(is_const));
self.build_type(t, true);
}
@ -106,7 +112,6 @@ impl CDecl {
}
fn write<F: Write>(&self, out: &mut SourceWriter<F>, ident: Option<&str>) {
// Write the type-specifier and type-qualifier first
if self.type_qualifers.len() != 0 {
write!(out, "{} {}", self.type_qualifers, self.type_name);
@ -126,30 +131,22 @@ impl CDecl {
}
// Write the left part of declarators before the identifier
let mut iter_rev = self.declarators.iter()
.rev()
.peekable();
let mut iter_rev = self.declarators.iter().rev().peekable();
while let Some(declarator) = iter_rev.next() {
let next_is_pointer = iter_rev.peek().map_or(false, |x| x.is_ptr());
match declarator {
&CDeclarator::Ptr(ref is_const) => {
if *is_const {
out.write("*const ");
} else {
out.write("*");
}
&CDeclarator::Ptr(ref is_const) => if *is_const {
out.write("*const ");
} else {
out.write("*");
},
&CDeclarator::Array(..) => {
if next_is_pointer {
out.write("(");
}
&CDeclarator::Array(..) => if next_is_pointer {
out.write("(");
},
&CDeclarator::Func(..) => {
if next_is_pointer {
out.write("(");
}
&CDeclarator::Func(..) => if next_is_pointer {
out.write("(");
},
}
}
@ -167,7 +164,7 @@ impl CDecl {
match declarator {
&CDeclarator::Ptr(..) => {
last_was_pointer = true;
},
}
&CDeclarator::Array(ref constant) => {
if last_was_pointer {
out.write(")");
@ -175,7 +172,7 @@ impl CDecl {
write!(out, "[{}]", constant);
last_was_pointer = false;
},
}
&CDeclarator::Func(ref args, layout_vertical) => {
if last_was_pointer {
out.write(")");
@ -212,7 +209,7 @@ impl CDecl {
out.write(")");
last_was_pointer = true;
},
}
}
}
}

View File

@ -266,7 +266,7 @@ impl Default for ConstantConfig {
}
/// Settings to apply when parsing.
#[derive( Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]

View File

@ -24,18 +24,18 @@ impl Dependencies {
pub fn sort(&mut self) {
// Sort enums and opaque structs into their own layers because they don't
// depend on each other or anything else.
let ordering = |a: &ItemContainer, b: &ItemContainer| {
match (a, b) {
(&ItemContainer::Enum(ref x), &ItemContainer::Enum(ref y)) => x.name.cmp(&y.name),
(&ItemContainer::Enum(_), _) => Ordering::Less,
(_, &ItemContainer::Enum(_)) => Ordering::Greater,
let ordering = |a: &ItemContainer, b: &ItemContainer| match (a, b) {
(&ItemContainer::Enum(ref x), &ItemContainer::Enum(ref y)) => x.name.cmp(&y.name),
(&ItemContainer::Enum(_), _) => Ordering::Less,
(_, &ItemContainer::Enum(_)) => Ordering::Greater,
(&ItemContainer::OpaqueItem(ref x), &ItemContainer::OpaqueItem(ref y)) => x.name.cmp(&y.name),
(&ItemContainer::OpaqueItem(_), _) => Ordering::Less,
(_, &ItemContainer::OpaqueItem(_)) => Ordering::Greater,
_ => Ordering::Equal,
(&ItemContainer::OpaqueItem(ref x), &ItemContainer::OpaqueItem(ref y)) => {
x.name.cmp(&y.name)
}
(&ItemContainer::OpaqueItem(_), _) => Ordering::Less,
(_, &ItemContainer::OpaqueItem(_)) => Ordering::Greater,
_ => Ordering::Equal,
};
self.order.sort_by(ordering);

View File

@ -31,7 +31,7 @@ pub enum AnnotationValue {
/// A set of annotations specified by a document comment.
#[derive(Debug, Clone)]
pub struct AnnotationSet {
annotations: HashMap<String, AnnotationValue>
annotations: HashMap<String, AnnotationValue>,
}
impl AnnotationSet {
@ -50,8 +50,8 @@ impl AnnotationSet {
for attr in attrs {
if attr.style == syn::AttrStyle::Outer {
if let syn::MetaItem::NameValue(
ref name, syn::Lit::Str(ref comment, _)) = attr.value
if let syn::MetaItem::NameValue(ref name, syn::Lit::Str(ref comment, _)) =
attr.value
{
if &*name == "doc" {
let line = comment.trim_left_matches("///").trim();
@ -76,9 +76,7 @@ impl AnnotationSet {
let annotation = &line[9..];
// Split the annotation in two
let parts: Vec<&str> = annotation.split("=")
.map(|x| x.trim())
.collect();
let parts: Vec<&str> = annotation.split("=").map(|x| x.trim()).collect();
if parts.len() > 2 {
return Err(format!("Couldn't parse {}.", line));
@ -104,15 +102,18 @@ impl AnnotationSet {
annotations.insert(name.to_string(), AnnotationValue::Bool(x));
continue;
}
annotations.insert(name.to_string(), if value.len() == 0 {
AnnotationValue::Atom(None)
} else {
AnnotationValue::Atom(Some(value.to_string()))
});
annotations.insert(
name.to_string(),
if value.len() == 0 {
AnnotationValue::Atom(None)
} else {
AnnotationValue::Atom(Some(value.to_string()))
},
);
}
Ok(AnnotationSet {
annotations: annotations
annotations: annotations,
})
}
@ -136,12 +137,14 @@ impl AnnotationSet {
}
pub fn parse_atom<T>(&self, name: &str) -> Option<T>
where T: Default + FromStr
where
T: Default + FromStr,
{
match self.annotations.get(name) {
Some(&AnnotationValue::Atom(ref x)) => {
Some(x.as_ref().map_or(T::default(), |y| { y.parse::<T>().ok().unwrap() }))
}
Some(&AnnotationValue::Atom(ref x)) => Some(
x.as_ref()
.map_or(T::default(), |y| y.parse::<T>().ok().unwrap()),
),
_ => None,
}
}
@ -154,11 +157,12 @@ fn parse_list(list: &str) -> Option<Vec<String>> {
}
match (list.chars().next(), list.chars().last()) {
(Some('['), Some(']')) => {
Some(list[1..list.len() - 1].split(',')
.map(|x| x.trim().to_string())
.collect())
}
_ => None
(Some('['), Some(']')) => Some(
list[1..list.len() - 1]
.split(',')
.map(|x| x.trim().to_string())
.collect(),
),
_ => None,
}
}

View File

@ -63,15 +63,9 @@ impl Cfg {
pub fn append(parent: &Option<Cfg>, child: Option<Cfg>) -> Option<Cfg> {
match (parent, child) {
(&None, None) => {
None
}
(&None, Some(child)) => {
Some(child)
}
(&Some(ref parent), None) => {
Some(parent.clone())
}
(&None, None) => None,
(&None, Some(child)) => Some(child),
(&Some(ref parent), None) => Some(parent.clone()),
(&Some(ref parent), Some(ref child)) => {
Some(Cfg::All(vec![parent.clone(), child.clone()]))
}
@ -87,11 +81,10 @@ impl Cfg {
}
match &attr.value {
&syn::MetaItem::Word(..) => { }
&syn::MetaItem::NameValue(..) => { }
&syn::MetaItem::Word(..) => {}
&syn::MetaItem::NameValue(..) => {}
&syn::MetaItem::List(ref ident, ref nested) => {
if ident.as_ref() != "cfg" ||
nested.len() != 1 {
if ident.as_ref() != "cfg" || nested.len() != 1 {
continue;
}
@ -117,30 +110,23 @@ impl Cfg {
&syn::NestedMetaItem::MetaItem(syn::MetaItem::NameValue(ref ident, ref value)) => {
match value {
&syn::Lit::Str(ref value, _) => {
Some(Cfg::Named(ident.as_ref().to_owned(),
value.clone()))
}
_ => {
None
Some(Cfg::Named(ident.as_ref().to_owned(), value.clone()))
}
_ => None,
}
}
&syn::NestedMetaItem::MetaItem(syn::MetaItem::List(ref ident, ref nested)) => {
match ident.as_ref() {
"any" => {
if let Some(configs) = Cfg::load_list(nested) {
Some(Cfg::Any(configs))
} else {
None
}
}
"all" => {
if let Some(configs) = Cfg::load_list(nested) {
Some(Cfg::All(configs))
} else {
None
}
}
"any" => if let Some(configs) = Cfg::load_list(nested) {
Some(Cfg::Any(configs))
} else {
None
},
"all" => if let Some(configs) = Cfg::load_list(nested) {
Some(Cfg::All(configs))
} else {
None
},
"not" => {
if nested.len() != 1 {
return None;
@ -152,12 +138,10 @@ impl Cfg {
None
}
}
_ => {
None
}
_ => None,
}
}
_ => { None }
_ => None,
}
}
@ -186,12 +170,10 @@ impl Cfg {
let key = DefineKey::load(key);
match key {
DefineKey::Boolean(key_name) => {
if cfg_name == key_name {
return true;
}
}
DefineKey::Named(..) => { }
DefineKey::Boolean(key_name) => if cfg_name == key_name {
return true;
},
DefineKey::Named(..) => {}
}
}
@ -202,10 +184,9 @@ impl Cfg {
let key = DefineKey::load(key);
match key {
DefineKey::Boolean(..) => { }
DefineKey::Boolean(..) => {}
DefineKey::Named(key_name, key_value) => {
if cfg_name == key_name &&
cfg_value == key_value {
if cfg_name == key_name && cfg_value == key_value {
return true;
}
}
@ -214,15 +195,9 @@ impl Cfg {
false
}
&Cfg::Any(ref cfgs) => {
cfgs.iter().all(|x| x.has_defines(config))
}
&Cfg::All(ref cfgs) => {
cfgs.iter().all(|x| x.has_defines(config))
}
&Cfg::Not(ref cfg) => {
cfg.has_defines(config)
}
&Cfg::Any(ref cfgs) => cfgs.iter().all(|x| x.has_defines(config)),
&Cfg::All(ref cfgs) => cfgs.iter().all(|x| x.has_defines(config)),
&Cfg::Not(ref cfg) => cfg.has_defines(config),
}
}
@ -235,12 +210,10 @@ impl Cfg {
let key = DefineKey::load(key);
match key {
DefineKey::Boolean(key_name) => {
if cfg_name == key_name {
define = define_value;
}
}
DefineKey::Named(..) => { }
DefineKey::Boolean(key_name) => if cfg_name == key_name {
define = define_value;
},
DefineKey::Named(..) => {}
}
}
@ -255,10 +228,9 @@ impl Cfg {
let key = DefineKey::load(key);
match key {
DefineKey::Boolean(..) => { }
DefineKey::Boolean(..) => {}
DefineKey::Named(key_name, key_value) => {
if cfg_name == key_name &&
cfg_value == key_value {
if cfg_name == key_name && cfg_value == key_value {
define = define_value;
}
}

View File

@ -20,40 +20,30 @@ impl LiteralExpr {
&syn::ExprKind::Lit(syn::Lit::Str(ref text, ..)) => {
Ok(LiteralExpr(format!("u8\"{}\"", text)))
}
&syn::ExprKind::Lit(syn::Lit::Byte(value)) => {
Ok(LiteralExpr(format!("{}", value)))
}
&syn::ExprKind::Lit(syn::Lit::Char(value)) => {
Ok(LiteralExpr(format!("{}", value)))
}
&syn::ExprKind::Lit(syn::Lit::Int(value, ref ty)) => {
match ty {
&syn::IntTy::Usize |
&syn::IntTy::U8 |
&syn::IntTy::U16 |
&syn::IntTy::U32 |
&syn::IntTy::U64 |
&syn::IntTy::Unsuffixed => {
Ok(LiteralExpr(format!("{}", value)))
}
&syn::IntTy::Isize |
&syn::IntTy::I8 |
&syn::IntTy::I16 |
&syn::IntTy::I32 |
&syn::IntTy::I64 => {
unsafe {
Ok(LiteralExpr(format!("{}", mem::transmute::<u64, i64>(value))))
}
}
}
}
&syn::ExprKind::Lit(syn::Lit::Byte(value)) => Ok(LiteralExpr(format!("{}", value))),
&syn::ExprKind::Lit(syn::Lit::Char(value)) => Ok(LiteralExpr(format!("{}", value))),
&syn::ExprKind::Lit(syn::Lit::Int(value, ref ty)) => match ty {
&syn::IntTy::Usize |
&syn::IntTy::U8 |
&syn::IntTy::U16 |
&syn::IntTy::U32 |
&syn::IntTy::U64 |
&syn::IntTy::Unsuffixed => Ok(LiteralExpr(format!("{}", value))),
&syn::IntTy::Isize |
&syn::IntTy::I8 |
&syn::IntTy::I16 |
&syn::IntTy::I32 |
&syn::IntTy::I64 => unsafe {
Ok(LiteralExpr(
format!("{}", mem::transmute::<u64, i64>(value)),
))
},
},
&syn::ExprKind::Lit(syn::Lit::Float(ref value, ref _ty)) => {
Ok(LiteralExpr(format!("{}", value)))
}
&syn::ExprKind::Lit(syn::Lit::Bool(value)) => {
Ok(LiteralExpr(format!("{}", value)))
}
_ => Err("Unsupported literal expression.".to_owned())
&syn::ExprKind::Lit(syn::Lit::Bool(value)) => Ok(LiteralExpr(format!("{}", value))),
_ => Err("Unsupported literal expression.".to_owned()),
}
}
}
@ -70,12 +60,13 @@ pub struct Constant {
impl Constant {
pub fn load(name: String,
ty: &syn::Ty,
expr: &syn::Expr,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Constant, String>
{
pub fn load(
name: String,
ty: &syn::Ty,
expr: &syn::Expr,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Constant, String> {
let ty = Type::load(ty)?;
if ty.is_none() {
@ -123,9 +114,7 @@ impl Item for Constant {
impl Source for Constant {
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
if config.constant.allow_static_const &&
config.language == Language::Cxx
{
if config.constant.allow_static_const && config.language == Language::Cxx {
if let Type::ConstPtr(..) = self.ty {
out.write("static ");
} else {

View File

@ -11,7 +11,7 @@ use bindgen::writer::{Source, SourceWriter};
#[derive(Debug, Clone)]
pub struct Documentation {
pub doc_comment: Vec<String>
pub doc_comment: Vec<String>,
}
impl Documentation {
@ -26,8 +26,8 @@ impl Documentation {
// step through rust. In that case they are stored as doc
// attributes and the leading three slashes (and optional space)
// are not included.
if let syn::MetaItem::NameValue(
ref name, syn::Lit::Str(ref comment, _)) = attr.value
if let syn::MetaItem::NameValue(ref name, syn::Lit::Str(ref comment, _)) =
attr.value
{
if &*name == "doc" {
let line = if attr.is_sugared_doc {
@ -46,9 +46,7 @@ impl Documentation {
}
}
Documentation {
doc_comment: doc,
}
Documentation { doc_comment: doc }
}
pub fn none() -> Self {

View File

@ -7,9 +7,9 @@ use std::io::Write;
use syn;
use bindgen::config::{Config, Language};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, ItemContainer, Item, Repr};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, Item, ItemContainer, Repr};
use bindgen::rename::{IdentifierType, RenameRule};
use bindgen::utilities::{find_first_some};
use bindgen::utilities::find_first_some;
use bindgen::writer::{Source, SourceWriter};
#[derive(Debug, Clone)]
@ -23,22 +23,18 @@ pub struct Enum {
}
impl Enum {
pub fn load(name: String,
variants: &Vec<syn::Variant>,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Enum, String>
{
pub fn load(
name: String,
variants: &Vec<syn::Variant>,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Enum, String> {
let repr = Repr::load(attrs);
if repr != Repr::C &&
repr != Repr::USize &&
repr != Repr::U32 &&
repr != Repr::U16 &&
repr != Repr::U8 &&
repr != Repr::ISize &&
repr != Repr::I32 &&
repr != Repr::I16 &&
repr != Repr::I8 {
if repr != Repr::C && repr != Repr::USize && repr != Repr::U32 && repr != Repr::U16
&& repr != Repr::U8 && repr != Repr::ISize && repr != Repr::I32
&& repr != Repr::I16 && repr != Repr::I8
{
return Err("Enum not marked with a valid repr(prim) or repr(C).".to_owned());
}
@ -58,9 +54,11 @@ impl Enum {
None => { /* okay, we just use current */ }
}
values.push((variant.ident.to_string(),
current,
Documentation::load(&variant.attrs)));
values.push((
variant.ident.to_string(),
current,
Documentation::load(&variant.attrs),
));
current = current + 1;
}
_ => {
@ -117,20 +115,27 @@ impl Item for Enum {
{
let old = ::std::mem::replace(&mut self.values, Vec::new());
for (name, value, doc) in old {
self.values.push((format!("{}_{}", self.name, name), value, doc));
self.values
.push((format!("{}_{}", self.name, name), value, doc));
}
}
let rules = [self.annotations.parse_atom::<RenameRule>("rename-all"),
config.enumeration.rename_variants];
let rules = [
self.annotations.parse_atom::<RenameRule>("rename-all"),
config.enumeration.rename_variants,
];
if let Some(r) = find_first_some(&rules) {
self.values = self.values.iter()
.map(|x| (r.apply_to_pascal_case(&x.0,
IdentifierType::EnumVariant(self)),
x.1.clone(),
x.2.clone()))
.collect();
self.values = self.values
.iter()
.map(|x| {
(
r.apply_to_pascal_case(&x.0, IdentifierType::EnumVariant(self)),
x.1.clone(),
x.2.clone(),
)
})
.collect();
}
}
}

View File

@ -28,14 +28,14 @@ pub struct Function {
}
impl Function {
pub fn load(name: String,
decl: &syn::FnDecl,
extern_decl: bool,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Function, String>
{
let args = decl.inputs.iter()
.try_skip_map(|x| x.as_ident_and_type())?;
pub fn load(
name: String,
decl: &syn::FnDecl,
extern_decl: bool,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Function, String> {
let args = decl.inputs.iter().try_skip_map(|x| x.as_ident_and_type())?;
let ret = decl.output.as_type()?;
Ok(Function {
@ -78,15 +78,21 @@ impl Function {
}
pub fn rename_for_config(&mut self, config: &Config) {
let rules = [self.annotations.parse_atom::<RenameRule>("rename-all"),
config.function.rename_args];
let rules = [
self.annotations.parse_atom::<RenameRule>("rename-all"),
config.function.rename_args,
];
if let Some(r) = find_first_some(&rules) {
self.args = self.args.iter()
.map(|x| (r.apply_to_snake_case(&x.0,
IdentifierType::FunctionArg),
x.1.clone()))
.collect()
self.args = self.args
.iter()
.map(|x| {
(
r.apply_to_snake_case(&x.0, IdentifierType::FunctionArg),
x.1.clone(),
)
})
.collect()
}
}
}
@ -151,8 +157,9 @@ impl Source for Function {
let option_1 = out.measure(|out| write_1(self, config, out));
if (config.function.args == Layout::Auto && option_1 <= config.line_length) ||
config.function.args == Layout::Horizontal {
if (config.function.args == Layout::Auto && option_1 <= config.line_length)
|| config.function.args == Layout::Horizontal
{
write_1(self, config, out);
} else {
write_2(self, config, out);

View File

@ -24,12 +24,13 @@ pub struct Static {
impl Static {
pub fn load(name: String,
ty: &syn::Ty,
mutable: &syn::Mutability,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Static, String>
{
pub fn load(
name: String,
ty: &syn::Ty,
mutable: &syn::Mutability,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Static, String> {
let ty = Type::load(ty)?;
if ty.is_none() {
@ -83,7 +84,8 @@ impl Item for Static {
impl Source for Static {
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
out.write("extern ");
if let Type::ConstPtr(..) = self.ty { } else {
if let Type::ConstPtr(..) = self.ty {
} else {
if !self.mutable {
out.write("const ");
}

View File

@ -7,7 +7,8 @@ use std::mem;
use bindgen::config::Config;
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Static, Struct, Type, Typedef, Union};
use bindgen::ir::{AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Static, Struct, Type, Typedef,
Union};
use bindgen::library::Library;
use bindgen::monomorph::Monomorphs;
@ -20,9 +21,14 @@ pub trait Item {
fn container(&self) -> ItemContainer;
fn rename_for_config(&mut self, _config: &Config) { }
fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) { }
fn instantiate_monomorph(&self, _generics: &Vec<Type>, _library: &Library, _out: &mut Monomorphs) {
fn rename_for_config(&mut self, _config: &Config) {}
fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) {}
fn instantiate_monomorph(
&self,
_generics: &Vec<Type>,
_library: &Library,
_out: &mut Monomorphs,
) {
unreachable!("Cannot instantiate {} as a generic.", self.name())
}
}
@ -55,7 +61,7 @@ impl ItemContainer {
#[derive(Debug, Clone)]
pub enum ItemValue<T: Item> {
Cfg(Vec<T>),
Single(T)
Single(T),
}
#[derive(Debug, Clone)]
@ -85,15 +91,15 @@ impl<T: Item + Clone> ItemMap<T> {
(false, Some(&mut ItemValue::Single(_))) => {
return false;
}
_ => { }
_ => {}
}
if item.cfg().is_some() {
self.data.insert(item.name().to_owned(),
ItemValue::Cfg(vec![item]));
self.data
.insert(item.name().to_owned(), ItemValue::Cfg(vec![item]));
} else {
self.data.insert(item.name().to_owned(),
ItemValue::Single(item));
self.data
.insert(item.name().to_owned(), ItemValue::Single(item));
}
true
@ -109,9 +115,7 @@ impl<T: Item + Clone> ItemMap<T> {
let mut result = Vec::with_capacity(self.data.len());
for container in self.data.values() {
match container {
&ItemValue::Cfg(ref items) => {
result.extend_from_slice(items)
}
&ItemValue::Cfg(ref items) => result.extend_from_slice(items),
&ItemValue::Single(ref item) => {
result.push(item.clone());
}
@ -122,20 +126,15 @@ impl<T: Item + Clone> ItemMap<T> {
pub fn get_items(&self, name: &str) -> Option<Vec<ItemContainer>> {
match self.data.get(name) {
Some(&ItemValue::Cfg(ref items)) => {
Some(items.iter()
.map(|x| x.container())
.collect())
}
Some(&ItemValue::Single(ref item)) => {
Some(vec![item.container()])
}
Some(&ItemValue::Cfg(ref items)) => Some(items.iter().map(|x| x.container()).collect()),
Some(&ItemValue::Single(ref item)) => Some(vec![item.container()]),
None => None,
}
}
pub fn filter<F>(&mut self, callback: F)
where F: Fn(&T) -> bool
where
F: Fn(&T) -> bool,
{
let data = mem::replace(&mut self.data, BTreeMap::new());
@ -152,79 +151,69 @@ impl<T: Item + Clone> ItemMap<T> {
self.data.insert(name, ItemValue::Cfg(new_items));
}
}
ItemValue::Single(item) => {
if !callback(&item) {
self.data.insert(name, ItemValue::Single(item));
}
}
ItemValue::Single(item) => if !callback(&item) {
self.data.insert(name, ItemValue::Single(item));
},
}
}
}
pub fn for_all_items<F>(&self, mut callback: F)
where F: FnMut(&T)
where
F: FnMut(&T),
{
for container in self.data.values() {
match container {
&ItemValue::Cfg(ref items) => {
for item in items {
callback(item);
}
}
&ItemValue::Single(ref item) => {
callback(item)
}
&ItemValue::Cfg(ref items) => for item in items {
callback(item);
},
&ItemValue::Single(ref item) => callback(item),
}
}
}
pub fn for_all_items_mut<F>(&mut self, mut callback: F)
where F: FnMut(&mut T)
where
F: FnMut(&mut T),
{
for container in self.data.values_mut() {
match container {
&mut ItemValue::Cfg(ref mut items) => {
for item in items {
callback(item);
}
}
&mut ItemValue::Single(ref mut item) => {
callback(item)
}
&mut ItemValue::Cfg(ref mut items) => for item in items {
callback(item);
},
&mut ItemValue::Single(ref mut item) => callback(item),
}
}
}
#[allow(dead_code)]
pub fn for_items<F>(&self, name: &str, mut callback: F)
where F: FnMut(&T)
where
F: FnMut(&T),
{
match self.data.get(name) {
Some(&ItemValue::Cfg(ref items)) => {
for item in items {
callback(item);
}
}
Some(&ItemValue::Cfg(ref items)) => for item in items {
callback(item);
},
Some(&ItemValue::Single(ref item)) => {
callback(item);
}
None => { }
None => {}
}
}
pub fn for_items_mut<F>(&mut self, name: &str, mut callback: F)
where F: FnMut(&mut T)
where
F: FnMut(&mut T),
{
match self.data.get_mut(name) {
Some(&mut ItemValue::Cfg(ref mut items)) => {
for item in items {
callback(item);
}
}
Some(&mut ItemValue::Cfg(ref mut items)) => for item in items {
callback(item);
},
Some(&mut ItemValue::Single(ref mut item)) => {
callback(item);
}
None => { }
None => {}
}
}
}

View File

@ -8,7 +8,8 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Path, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer,
Path, Type};
use bindgen::library::Library;
use bindgen::mangle;
use bindgen::monomorph::Monomorphs;
@ -24,10 +25,12 @@ pub struct OpaqueItem {
}
impl OpaqueItem {
pub fn new(name: String,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> OpaqueItem {
pub fn new(
name: String,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> OpaqueItem {
OpaqueItem {
name: name,
generic_params: GenericParams::new(generics),
@ -59,12 +62,15 @@ impl Item for OpaqueItem {
ItemContainer::OpaqueItem(self.clone())
}
fn add_dependencies(&self, _: &Library, _: &mut Dependencies) {
}
fn add_dependencies(&self, _: &Library, _: &mut Dependencies) {}
fn instantiate_monomorph(&self, generic_values: &Vec<Type>, _library: &Library, out: &mut Monomorphs) {
assert!(self.generic_params.len() > 0 &&
self.generic_params.len() == generic_values.len());
fn instantiate_monomorph(
&self,
generic_values: &Vec<Type>,
_library: &Library,
out: &mut Monomorphs,
) {
assert!(self.generic_params.len() > 0 && self.generic_params.len() == generic_values.len());
let monomorph = OpaqueItem {
name: mangle::mangle_path(&self.name, generic_values),

View File

@ -35,8 +35,7 @@ impl GenericPath {
let generics = match &last_segment.parameters {
&syn::PathParameters::AngleBracketed(ref d) => {
d.types.iter()
.try_skip_map(|x| Type::load(x))?
d.types.iter().try_skip_map(|x| Type::load(x))?
}
&syn::PathParameters::Parenthesized(_) => {
return Err("Path contains parentheses.".to_owned());

View File

@ -48,47 +48,83 @@ impl Repr {
}
fn repr_c() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("C")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("C"))),
],
)
}
fn repr_usize() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("usize")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("usize"))),
],
)
}
fn repr_u32() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("u32")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("u32"))),
],
)
}
fn repr_u16() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("u16")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("u16"))),
],
)
}
fn repr_u8() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("u8")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("u8"))),
],
)
}
fn repr_isize() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("isize")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("isize"))),
],
)
}
fn repr_i32() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("i32")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("i32"))),
],
)
}
fn repr_i16() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("i16")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("i16"))),
],
)
}
fn repr_i8() -> syn::MetaItem {
syn::MetaItem::List(syn::Ident::new("repr"),
vec![syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("i8")))])
syn::MetaItem::List(
syn::Ident::new("repr"),
vec![
syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(syn::Ident::new("i8"))),
],
)
}
}

View File

@ -8,7 +8,8 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Repr, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer,
Repr, Type};
use bindgen::library::Library;
use bindgen::mangle;
use bindgen::monomorph::Monomorphs;
@ -28,20 +29,20 @@ pub struct Struct {
}
impl Struct {
pub fn load(name: String,
decl: &syn::VariantData,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Struct, String>
{
pub fn load(
name: String,
decl: &syn::VariantData,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Struct, String> {
if Repr::load(attrs) != Repr::C {
return Err("Struct is not marked #[repr(C)].".to_owned());
}
let (fields, tuple_struct) = match decl {
&syn::VariantData::Struct(ref fields) => {
let out = fields.iter()
.try_skip_map(|x| x.as_ident_and_type())?;
let out = fields.iter().try_skip_map(|x| x.as_ident_and_type())?;
(out, false)
}
&syn::VariantData::Tuple(ref fields) => {
@ -49,15 +50,17 @@ impl Struct {
let mut current = 0;
for field in fields {
if let Some(x) = Type::load(&field.ty)? {
out.push((format!("{}", current), x, Documentation::load(&field.attrs)));
out.push((
format!("{}", current),
x,
Documentation::load(&field.attrs),
));
current += 1;
}
}
(out, true)
}
&syn::VariantData::Unit => {
(vec![], false)
}
&syn::VariantData::Unit => (vec![], false),
};
Ok(Struct {
@ -122,8 +125,10 @@ impl Item for Struct {
}
fn rename_for_config(&mut self, config: &Config) {
let rules = [self.annotations.parse_atom::<RenameRule>("rename-all"),
config.structure.rename_fields];
let rules = [
self.annotations.parse_atom::<RenameRule>("rename-all"),
config.structure.rename_fields,
];
if let Some(o) = self.annotations.list("field-names") {
let mut overriden_fields = Vec::new();
@ -138,12 +143,16 @@ impl Item for Struct {
self.fields = overriden_fields;
} else if let Some(r) = find_first_some(&rules) {
self.fields = self.fields.iter()
.map(|x| (r.apply_to_snake_case(&x.0,
IdentifierType::StructMember),
x.1.clone(),
x.2.clone()))
.collect();
self.fields = self.fields
.iter()
.map(|x| {
(
r.apply_to_snake_case(&x.0, IdentifierType::StructMember),
x.1.clone(),
x.2.clone(),
)
})
.collect();
} else if self.tuple_struct {
// If we don't have any rules for a tuple struct, prefix them with
// an underscore so it still compiles
@ -159,20 +168,26 @@ impl Item for Struct {
}
}
fn instantiate_monomorph(&self, generic_values: &Vec<Type>, library: &Library, out: &mut Monomorphs) {
assert!(self.generic_params.len() > 0 &&
self.generic_params.len() == generic_values.len());
fn instantiate_monomorph(
&self,
generic_values: &Vec<Type>,
library: &Library,
out: &mut Monomorphs,
) {
assert!(self.generic_params.len() > 0 && self.generic_params.len() == generic_values.len());
let mappings = self.generic_params.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let mappings = self.generic_params
.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let monomorph = Struct {
name: mangle::mangle_path(&self.name, generic_values),
generic_params: GenericParams::default(),
fields: self.fields.iter()
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
fields: self.fields
.iter()
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
tuple_struct: self.tuple_struct,
cfg: self.cfg.clone(),
annotations: self.annotations.clone(),
@ -204,10 +219,13 @@ impl Source for Struct {
if config.documentation {
out.write_vertical_source_list(&self.fields, ListType::Cap(";"));
} else {
out.write_vertical_source_list(&self.fields.iter()
.map(|&(ref name, ref ty, _)| (name.clone(), ty.clone()))
.collect(),
ListType::Cap(";"));
out.write_vertical_source_list(
&self.fields
.iter()
.map(|&(ref name, ref ty, _)| (name.clone(), ty.clone()))
.collect(),
ListType::Cap(";"),
);
}
if config.language == Language::Cxx {
@ -227,39 +245,54 @@ impl Source for Struct {
out.new_line();
write!(out, "bool operator{}(const {}& {}) const", op, self.name, other);
write!(
out,
"bool operator{}(const {}& {}) const",
op,
self.name,
other
);
out.open_brace();
out.write("return ");
out.write_vertical_source_list(&self.fields.iter()
.map(|x| format!("{} {} {}.{}", x.0, op, other, x.0))
.collect(),
ListType::Join(&format!(" {}", conjuc)));
out.write_vertical_source_list(
&self.fields
.iter()
.map(|x| format!("{} {} {}.{}", x.0, op, other, x.0))
.collect(),
ListType::Join(&format!(" {}", conjuc)),
);
out.write(";");
out.close_brace(false);
};
if config.structure.derive_eq(&self.annotations) &&
!self.fields.is_empty() && self.fields.iter().all(|x| x.1.can_cmp_eq()) {
if config.structure.derive_eq(&self.annotations) && !self.fields.is_empty()
&& self.fields.iter().all(|x| x.1.can_cmp_eq())
{
emit_op("==", "&&");
}
if config.structure.derive_neq(&self.annotations) &&
!self.fields.is_empty() && self.fields.iter().all(|x| x.1.can_cmp_eq()) {
if config.structure.derive_neq(&self.annotations) && !self.fields.is_empty()
&& self.fields.iter().all(|x| x.1.can_cmp_eq())
{
emit_op("!=", "||");
}
if config.structure.derive_lt(&self.annotations) &&
self.fields.len() == 1 && self.fields[0].1.can_cmp_order() {
if config.structure.derive_lt(&self.annotations) && self.fields.len() == 1
&& self.fields[0].1.can_cmp_order()
{
emit_op("<", "&&");
}
if config.structure.derive_lte(&self.annotations) &&
self.fields.len() == 1 && self.fields[0].1.can_cmp_order() {
if config.structure.derive_lte(&self.annotations) && self.fields.len() == 1
&& self.fields[0].1.can_cmp_order()
{
emit_op("<=", "&&");
}
if config.structure.derive_gt(&self.annotations) &&
self.fields.len() == 1 && self.fields[0].1.can_cmp_order() {
if config.structure.derive_gt(&self.annotations) && self.fields.len() == 1
&& self.fields[0].1.can_cmp_order()
{
emit_op(">", "&&");
}
if config.structure.derive_gte(&self.annotations) &&
self.fields.len() == 1 && self.fields[0].1.can_cmp_order() {
if config.structure.derive_gte(&self.annotations) && self.fields.len() == 1
&& self.fields[0].1.can_cmp_order()
{
emit_op(">=", "&&");
}
}
@ -281,11 +314,16 @@ pub trait SynFieldHelpers {
impl SynFieldHelpers for syn::Field {
fn as_ident_and_type(&self) -> Result<Option<(String, Type, Documentation)>, String> {
let ident = self.ident.as_ref().ok_or(format!("field is missing identifier"))?.clone();
let ident = self.ident
.as_ref()
.ok_or(format!("field is missing identifier"))?
.clone();
let converted_ty = Type::load(&self.ty)?;
if let Some(x) = converted_ty {
Ok(Some((ident.to_string(), x, Documentation::load(&self.attrs))))
Ok(Some(
(ident.to_string(), x, Documentation::load(&self.attrs)),
))
} else {
Ok(None)
}

View File

@ -183,7 +183,13 @@ impl Type {
let converted = match converted {
Some(converted) => converted,
None => return Err("Cannot have a pointer to a zero sized type. If you are trying to represent `void*` use `c_void*`.".to_owned()),
None => {
return Err(
"Cannot have a pointer to a zero sized type. If you are \
trying to represent `void*` use `c_void*`."
.to_owned(),
)
}
};
match mut_ty.mutability {
@ -196,7 +202,13 @@ impl Type {
let converted = match converted {
Some(converted) => converted,
None => return Err("Cannot have a pointer to a zero sized type. If you are trying to represent `void*` use `c_void*`.".to_owned()),
None => {
return Err(
"Cannot have a pointer to a zero sized type. If you are \
trying to represent `void*` use `c_void*`."
.to_owned(),
)
}
};
match mut_ty.mutability {
@ -229,7 +241,7 @@ impl Type {
};
Type::Array(Box::new(converted), format!("{}", size))
},
}
&syn::Ty::Array(ref ty, syn::ConstExpr::Path(ref path)) => {
let converted = Type::load(ty)?;
@ -241,19 +253,18 @@ impl Type {
let path = GenericPath::load(path)?;
Type::Array(Box::new(converted), path.name)
},
}
&syn::Ty::BareFn(ref function) => {
let args = function.inputs.iter()
.try_skip_map(|x| Type::load(&x.ty))?;
let args = function.inputs.iter().try_skip_map(|x| Type::load(&x.ty))?;
let ret = function.output.as_type()?;
Type::FuncPtr(Box::new(ret), args)
},
}
&syn::Ty::Tup(ref fields) => {
if fields.len() == 0 {
return Ok(None);
}
return Err("Tuples are not supported types.".to_owned())
return Err("Tuples are not supported types.".to_owned());
}
_ => return Err("Unsupported type.".to_owned()),
};
@ -264,11 +275,9 @@ impl Type {
pub fn is_primitive_or_ptr_primitive(&self) -> bool {
match self {
&Type::Primitive(..) => true,
&Type::ConstPtr(ref x) => {
match x.as_ref() {
&Type::Primitive(..) => true,
_ => false,
}
&Type::ConstPtr(ref x) => match x.as_ref() {
&Type::Primitive(..) => true,
_ => false,
},
_ => false,
}
@ -287,9 +296,7 @@ impl Type {
let mut simplified = None;
if let &mut Type::Path(ref mut path) = self {
if path.name == "Option" &&
path.generics.len() == 1 &&
path.generics[0].is_repr_ptr() {
if path.name == "Option" && path.generics.len() == 1 && path.generics[0].is_repr_ptr() {
simplified = Some(path.generics.pop().unwrap());
}
}
@ -303,32 +310,28 @@ impl Type {
let mut current = self;
loop {
match current {
&Type::ConstPtr(ref ty) => { current = ty },
&Type::Ptr(ref ty) => { current = ty },
&Type::ConstPtr(ref ty) => current = ty,
&Type::Ptr(ref ty) => current = ty,
&Type::Path(ref path) => {
return Some(path.name.clone());
},
}
&Type::Primitive(..) => {
return None;
},
}
&Type::Array(..) => {
return None;
},
}
&Type::FuncPtr(..) => {
return None;
},
}
};
};
}
}
pub fn specialize(&self, mappings: &Vec<(&String, &Type)>) -> Type {
match self {
&Type::ConstPtr(ref ty) => {
Type::ConstPtr(Box::new(ty.specialize(mappings)))
}
&Type::Ptr(ref ty) => {
Type::Ptr(Box::new(ty.specialize(mappings)))
}
&Type::ConstPtr(ref ty) => Type::ConstPtr(Box::new(ty.specialize(mappings))),
&Type::Ptr(ref ty) => Type::Ptr(Box::new(ty.specialize(mappings))),
&Type::Path(ref path) => {
for &(param, value) in mappings {
if *path.name == *param {
@ -336,28 +339,32 @@ impl Type {
}
}
let specialized = GenericPath::new(path.name.clone(),
path.generics.iter()
.map(|x| x.specialize(mappings))
.collect());
let specialized = GenericPath::new(
path.name.clone(),
path.generics
.iter()
.map(|x| x.specialize(mappings))
.collect(),
);
Type::Path(specialized)
}
&Type::Primitive(ref primitive) => {
Type::Primitive(primitive.clone())
}
&Type::Primitive(ref primitive) => Type::Primitive(primitive.clone()),
&Type::Array(ref ty, ref constant) => {
Type::Array(Box::new(ty.specialize(mappings)), constant.clone())
}
&Type::FuncPtr(ref ret, ref args) => {
Type::FuncPtr(Box::new(ret.specialize(mappings)),
args.iter()
.map(|x| x.specialize(mappings))
.collect())
}
&Type::FuncPtr(ref ret, ref args) => Type::FuncPtr(
Box::new(ret.specialize(mappings)),
args.iter().map(|x| x.specialize(mappings)).collect(),
),
}
}
pub fn add_dependencies_ignoring_generics(&self, generic_params: &GenericParams, library: &Library, out: &mut Dependencies) {
pub fn add_dependencies_ignoring_generics(
&self,
generic_params: &GenericParams,
library: &Library,
out: &mut Dependencies,
) {
match self {
&Type::ConstPtr(ref ty) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
@ -382,11 +389,15 @@ impl Type {
}
}
} else {
warn!("Can't find {}. This usually means that this type was incompatible or not found.", path.name);
warn!(
"Can't find {}. This usually means that this type was incompatible or \
not found.",
path.name
);
}
}
}
&Type::Primitive(_) => { }
&Type::Primitive(_) => {}
&Type::Array(ref ty, _) => {
ty.add_dependencies_ignoring_generics(generic_params, library, out);
}
@ -412,18 +423,18 @@ impl Type {
ty.add_monomorphs(library, out);
}
&Type::Path(ref path) => {
if path.generics.len() == 0 ||
out.contains(&path) {
if path.generics.len() == 0 || out.contains(&path) {
return;
}
if let Some(items) = library.get_items(&path.name) {
for item in items {
item.deref().instantiate_monomorph(&path.generics, library, out);
item.deref()
.instantiate_monomorph(&path.generics, library, out);
}
}
}
&Type::Primitive(_) => { }
&Type::Primitive(_) => {}
&Type::Array(ref ty, _) => {
ty.add_monomorphs(library, out);
}
@ -453,10 +464,14 @@ impl Type {
path.name = mangled.clone();
path.generics = Vec::new();
} else {
error!("Cannot find a mangling for generic path {:?}. This usually means that a type referenced by this generic was incompatible or not found.", path);
error!(
"Cannot find a mangling for generic path {:?}. This usually means that a \
type referenced by this generic was incompatible or not found.",
path
);
}
}
&mut Type::Primitive(_) => { }
&mut Type::Primitive(_) => {}
&mut Type::Array(ref mut ty, _) => {
ty.mangle_paths(monomorphs);
}
@ -525,12 +540,10 @@ impl SynFnRetTyHelpers for syn::FunctionRetTy {
fn as_type(&self) -> Result<Type, String> {
match self {
&syn::FunctionRetTy::Default => Ok(Type::Primitive(PrimitiveType::Void)),
&syn::FunctionRetTy::Ty(ref t) => {
if let Some(x) = Type::load(t)? {
Ok(x)
} else {
Ok(Type::Primitive(PrimitiveType::Void))
}
&syn::FunctionRetTy::Ty(ref t) => if let Some(x) = Type::load(t)? {
Ok(x)
} else {
Ok(Type::Primitive(PrimitiveType::Void))
},
}
}

View File

@ -9,7 +9,8 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Path, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer,
Path, Type};
use bindgen::library::Library;
use bindgen::mangle;
use bindgen::monomorph::Monomorphs;
@ -27,11 +28,13 @@ pub struct Typedef {
}
impl Typedef {
pub fn load(name: String,
ty: &syn::Ty,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Typedef, String> {
pub fn load(
name: String,
ty: &syn::Ty,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Typedef, String> {
if let Some(x) = Type::load(ty)? {
Ok(Typedef {
name: name,
@ -58,15 +61,18 @@ impl Typedef {
match self.aliased.get_root_path() {
Some(alias_path) => {
if out.contains_key(&alias_path) {
warn!("Multiple typedef's with annotations for {}. Ignoring annotations from {}.",
alias_path, self.name);
warn!(
"Multiple typedef's with annotations for {}. Ignoring annotations from {}.",
alias_path,
self.name
);
return;
}
out.insert(alias_path, self.annotations.clone());
self.annotations = AnnotationSet::new();
}
None => { }
None => {}
}
}
@ -111,16 +117,22 @@ impl Item for Typedef {
}
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
self.aliased.add_dependencies_ignoring_generics(&self.generic_params, library, out);
self.aliased
.add_dependencies_ignoring_generics(&self.generic_params, library, out);
}
fn instantiate_monomorph(&self, generic_values: &Vec<Type>, library: &Library, out: &mut Monomorphs) {
assert!(self.generic_params.len() > 0 &&
self.generic_params.len() == generic_values.len());
fn instantiate_monomorph(
&self,
generic_values: &Vec<Type>,
library: &Library,
out: &mut Monomorphs,
) {
assert!(self.generic_params.len() > 0 && self.generic_params.len() == generic_values.len());
let mappings = self.generic_params.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let mappings = self.generic_params
.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let monomorph = Typedef {
name: mangle::mangle_path(&self.name, generic_values),

View File

@ -8,7 +8,8 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Repr, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, Item, ItemContainer,
Repr, Type};
use bindgen::ir::SynFieldHelpers;
use bindgen::library::Library;
use bindgen::mangle;
@ -29,20 +30,20 @@ pub struct Union {
}
impl Union {
pub fn load(name: String,
decl: &syn::VariantData,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Union, String>
{
pub fn load(
name: String,
decl: &syn::VariantData,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Union, String> {
if Repr::load(attrs) != Repr::C {
return Err("Union is not marked #[repr(C)].".to_owned());
}
let (fields, tuple_union) = match decl {
&syn::VariantData::Struct(ref fields) => {
let out = fields.iter()
.try_skip_map(|x| x.as_ident_and_type())?;
let out = fields.iter().try_skip_map(|x| x.as_ident_and_type())?;
(out, false)
}
&syn::VariantData::Tuple(ref fields) => {
@ -50,15 +51,17 @@ impl Union {
let mut current = 0;
for field in fields {
if let Some(x) = Type::load(&field.ty)? {
out.push((format!("{}", current), x, Documentation::load(&field.attrs)));
out.push((
format!("{}", current),
x,
Documentation::load(&field.attrs),
));
current += 1;
}
}
(out, true)
}
&syn::VariantData::Unit => {
(vec![], false)
}
&syn::VariantData::Unit => (vec![], false),
};
Ok(Union {
@ -123,8 +126,10 @@ impl Item for Union {
}
fn rename_for_config(&mut self, config: &Config) {
let rules = [self.annotations.parse_atom::<RenameRule>("rename-all"),
config.structure.rename_fields];
let rules = [
self.annotations.parse_atom::<RenameRule>("rename-all"),
config.structure.rename_fields,
];
if let Some(o) = self.annotations.list("field-names") {
let mut overriden_fields = Vec::new();
@ -139,12 +144,16 @@ impl Item for Union {
self.fields = overriden_fields;
} else if let Some(r) = find_first_some(&rules) {
self.fields = self.fields.iter()
.map(|x| (r.apply_to_snake_case(&x.0,
IdentifierType::StructMember),
x.1.clone(),
x.2.clone()))
.collect();
self.fields = self.fields
.iter()
.map(|x| {
(
r.apply_to_snake_case(&x.0, IdentifierType::StructMember),
x.1.clone(),
x.2.clone(),
)
})
.collect();
} else if self.tuple_union {
// If we don't have any rules for a tuple union, prefix them with
// an underscore so it still compiles
@ -160,20 +169,26 @@ impl Item for Union {
}
}
fn instantiate_monomorph(&self, generic_values: &Vec<Type>, library: &Library, out: &mut Monomorphs) {
assert!(self.generic_params.len() > 0 &&
self.generic_params.len() == generic_values.len());
fn instantiate_monomorph(
&self,
generic_values: &Vec<Type>,
library: &Library,
out: &mut Monomorphs,
) {
assert!(self.generic_params.len() > 0 && self.generic_params.len() == generic_values.len());
let mappings = self.generic_params.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let mappings = self.generic_params
.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let monomorph = Union {
name: mangle::mangle_path(&self.name, generic_values),
generic_params: GenericParams::default(),
fields: self.fields.iter()
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
fields: self.fields
.iter()
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
tuple_union: self.tuple_union,
cfg: self.cfg.clone(),
annotations: self.annotations.clone(),
@ -205,10 +220,13 @@ impl Source for Union {
if config.documentation {
out.write_vertical_source_list(&self.fields, ListType::Cap(";"));
} else {
out.write_vertical_source_list(&self.fields.iter()
.map(|&(ref name, ref ty, _)| (name.clone(), ty.clone()))
.collect(),
ListType::Cap(";"));
out.write_vertical_source_list(
&self.fields
.iter()
.map(|&(ref name, ref ty, _)| (name.clone(), ty.clone()))
.collect(),
ListType::Cap(";"),
);
}
if config.language == Language::C {

View File

@ -8,7 +8,7 @@ use std::mem;
use bindgen::bindings::Bindings;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{Constant, Enum, Function, ItemContainer, ItemMap, Item};
use bindgen::ir::{Constant, Enum, Function, Item, ItemContainer, ItemMap};
use bindgen::ir::{OpaqueItem, Path, Static, Struct, Typedef, Union};
use bindgen::monomorph::Monomorphs;
@ -26,15 +26,17 @@ pub struct Library {
}
impl Library {
pub fn new(config: Config,
constants: ItemMap<Constant>,
globals: ItemMap<Static>,
enums: ItemMap<Enum>,
structs: ItemMap<Struct>,
unions: ItemMap<Union>,
opaque_items: ItemMap<OpaqueItem>,
typedefs: ItemMap<Typedef>,
functions: Vec<Function>) -> Library {
pub fn new(
config: Config,
constants: ItemMap<Constant>,
globals: ItemMap<Static>,
enums: ItemMap<Enum>,
structs: ItemMap<Struct>,
unions: ItemMap<Union>,
opaque_items: ItemMap<OpaqueItem>,
typedefs: ItemMap<Typedef>,
functions: Vec<Function>,
) -> Library {
Library {
config: config,
constants: constants,
@ -75,11 +77,13 @@ impl Library {
let globals = self.globals.to_vec();
let functions = mem::replace(&mut self.functions, Vec::new());
Ok(Bindings::new(self.config.clone(),
constants,
globals,
items,
functions))
Ok(Bindings::new(
self.config.clone(),
constants,
globals,
items,
functions,
))
}
pub fn get_items(&self, p: &Path) -> Option<Vec<ItemContainer>> {
@ -113,63 +117,73 @@ impl Library {
// TODO
let mut transferred = false;
self.enums.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
self.enums
.for_items_mut(&alias_path, |x| if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
transferred = true;
} else {
warn!("Can't transfer annotations from typedef to alias ({}) that already has annotations.",
alias_path);
}
});
warn!(
"Can't transfer annotations from typedef to alias ({}) \
that already has annotations.",
alias_path
);
});
if transferred {
continue;
}
self.structs.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
self.structs
.for_items_mut(&alias_path, |x| if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
transferred = true;
} else {
warn!("Can't transfer annotations from typedef to alias ({}) that already has annotations.",
alias_path);
}
});
warn!(
"Can't transfer annotations from typedef to alias ({}) \
that already has annotations.",
alias_path
);
});
if transferred {
continue;
}
self.unions.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
self.unions
.for_items_mut(&alias_path, |x| if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
transferred = true;
} else {
warn!("Can't transfer annotations from typedef to alias ({}) that already has annotations.",
alias_path);
}
});
warn!(
"Can't transfer annotations from typedef to alias ({}) \
that already has annotations.",
alias_path
);
});
if transferred {
continue;
}
self.opaque_items.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
self.opaque_items
.for_items_mut(&alias_path, |x| if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
transferred = true;
} else {
warn!("Can't transfer annotations from typedef to alias ({}) that already has annotations.",
alias_path);
}
});
warn!(
"Can't transfer annotations from typedef to alias ({}) \
that already has annotations.",
alias_path
);
});
if transferred {
continue;
}
self.typedefs.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
self.typedefs
.for_items_mut(&alias_path, |x| if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
transferred = true;
} else {
warn!("Can't transfer annotations from typedef to alias ({}) that already has annotations.",
alias_path);
}
});
warn!(
"Can't transfer annotations from typedef to alias ({}) \
that already has annotations.",
alias_path
);
});
if transferred {
continue;
}
@ -178,9 +192,12 @@ impl Library {
fn rename_items(&mut self) {
let config = &self.config;
self.structs.for_all_items_mut(|x| x.rename_for_config(config));
self.unions.for_all_items_mut(|x| x.rename_for_config(config));
self.enums.for_all_items_mut(|x| x.rename_for_config(config));
self.structs
.for_all_items_mut(|x| x.rename_for_config(config));
self.unions
.for_all_items_mut(|x| x.rename_for_config(config));
self.enums
.for_all_items_mut(|x| x.rename_for_config(config));
for item in &mut self.functions {
item.rename_for_config(&self.config);
@ -202,7 +219,7 @@ impl Library {
});
for x in &mut self.functions {
x.simplify_option_to_ptr();
};
}
}
fn instantiate_monomorphs(&mut self) {
@ -243,9 +260,12 @@ impl Library {
self.typedefs.filter(|x| x.generic_params.len() > 0);
// Mangle the paths that remain
self.unions.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
self.structs.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
self.typedefs.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
self.unions
.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
self.structs
.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
self.typedefs
.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
for x in &mut self.functions {
x.mangle_paths(&monomorphs);
}

View File

@ -9,7 +9,10 @@ pub fn mangle_path(name: &str, generic_values: &[Type]) -> String {
}
fn internal_mangle_path(name: &str, generic_values: &[Type], last_in_parent: bool) -> String {
assert!(!name.contains("_"), format!("name '{}' contains an underscore", name));
assert!(
!name.contains("_"),
format!("name '{}' contains an underscore", name)
);
if generic_values.is_empty() {
return String::from(name);
@ -26,17 +29,16 @@ fn internal_mangle_path(name: &str, generic_values: &[Type], last_in_parent: boo
let is_last = i == generic_values.len() - 1;
match ty {
&Type::Path(ref path) => {
out.push_str(&internal_mangle_path(&path.name,
&path.generics,
last_in_parent && is_last));
out.push_str(&internal_mangle_path(
&path.name,
&path.generics,
last_in_parent && is_last,
));
}
&Type::Primitive(ref primitive) => {
out.push_str(primitive.to_repr_rust());
}
&Type::ConstPtr(..) |
&Type::Ptr(..) |
&Type::Array(..)|
&Type::FuncPtr(..) => {
&Type::ConstPtr(..) | &Type::Ptr(..) | &Type::Array(..) | &Type::FuncPtr(..) => {
unimplemented!()
}
}
@ -67,30 +69,40 @@ fn generics() {
}
// Foo<f32> => Foo_f32
assert_eq!(mangle_path("Foo", &vec![float()]),
"Foo_f32");
assert_eq!(mangle_path("Foo", &vec![float()]), "Foo_f32");
// Foo<Bar<f32>> => Foo_Bar_f32
assert_eq!(mangle_path("Foo", &vec![generic_path("Bar", &[float()])]),
"Foo_Bar_f32");
assert_eq!(
mangle_path("Foo", &vec![generic_path("Bar", &[float()])]),
"Foo_Bar_f32"
);
// Foo<Bar> => Foo_Bar
assert_eq!(mangle_path("Foo", &[path("Bar")]),
"Foo_Bar");
assert_eq!(mangle_path("Foo", &[path("Bar")]), "Foo_Bar");
// Foo<Bar<T>> => Foo_Bar_T
assert_eq!(mangle_path("Foo", &[generic_path("Bar", &[path("T")])]),
"Foo_Bar_T");
assert_eq!(
mangle_path("Foo", &[generic_path("Bar", &[path("T")])]),
"Foo_Bar_T"
);
// Foo<Bar<T>, E> => Foo_Bar_T_____E
assert_eq!(mangle_path("Foo", &[generic_path("Bar", &[path("T")]),
path("E")]),
"Foo_Bar_T_____E");
assert_eq!(
mangle_path("Foo", &[generic_path("Bar", &[path("T")]), path("E")]),
"Foo_Bar_T_____E"
);
// Foo<Bar<T>, Bar<E>> => Foo_Bar_T_____Bar_E
assert_eq!(mangle_path("Foo", &[generic_path("Bar", &[path("T")]),
generic_path("Bar", &[path("E")])]),
"Foo_Bar_T_____Bar_E");
assert_eq!(
mangle_path(
"Foo",
&[
generic_path("Bar", &[path("T")]),
generic_path("Bar", &[path("E")])
]
),
"Foo_Bar_T_____Bar_E"
);
}
#[test]
@ -100,6 +112,5 @@ fn invalid() {
// foo_bar<u32> => foo_bar_f32
let t = Type::Primitive(PrimitiveType::UInt32);
assert_eq!(mangle_path("foo_bar", &vec![t]),
"foo_bar_u32");
assert_eq!(mangle_path("foo_bar", &vec![t]), "foo_bar_u32");
}

View File

@ -15,8 +15,8 @@ macro_rules! deserialize_enum_str {
impl ::serde::de::Visitor for Visitor {
type Value = $name;
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
formatter.write_str("$name")
fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.write_str("$name")
}
fn visit_str<E>(self, v: &str) -> Result<$name, E>

View File

@ -21,55 +21,52 @@ impl Monomorphs {
self.replacements.contains_key(path)
}
pub fn insert_struct(&mut self,
generic: &Struct,
monomorph: Struct,
parameters: Vec<Type>) {
pub fn insert_struct(&mut self, generic: &Struct, monomorph: Struct, parameters: Vec<Type>) {
let replacement_path = GenericPath::new(generic.name.clone(), parameters);
debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));
self.replacements.insert(replacement_path, monomorph.name.clone());
self.replacements
.insert(replacement_path, monomorph.name.clone());
self.structs.push(monomorph);
}
pub fn insert_union(&mut self,
generic: &Union,
monomorph: Union,
parameters: Vec<Type>) {
pub fn insert_union(&mut self, generic: &Union, monomorph: Union, parameters: Vec<Type>) {
let replacement_path = GenericPath::new(generic.name.clone(), parameters);
debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));
self.replacements.insert(replacement_path, monomorph.name.clone());
self.replacements
.insert(replacement_path, monomorph.name.clone());
self.unions.push(monomorph);
}
pub fn insert_opaque(&mut self,
generic: &OpaqueItem,
monomorph: OpaqueItem,
parameters: Vec<Type>) {
pub fn insert_opaque(
&mut self,
generic: &OpaqueItem,
monomorph: OpaqueItem,
parameters: Vec<Type>,
) {
let replacement_path = GenericPath::new(generic.name.clone(), parameters);
debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));
self.replacements.insert(replacement_path, monomorph.name.clone());
self.replacements
.insert(replacement_path, monomorph.name.clone());
self.opaques.push(monomorph);
}
pub fn insert_typedef(&mut self,
generic: &Typedef,
monomorph: Typedef,
parameters: Vec<Type>) {
pub fn insert_typedef(&mut self, generic: &Typedef, monomorph: Typedef, parameters: Vec<Type>) {
let replacement_path = GenericPath::new(generic.name.clone(), parameters);
debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));
self.replacements.insert(replacement_path, monomorph.name.clone());
self.replacements
.insert(replacement_path, monomorph.name.clone());
self.typedefs.push(monomorph);
}

View File

@ -14,12 +14,14 @@ use bindgen::ir::{AnnotationSet, Cfg, Constant, Documentation, Enum, Function, G
use bindgen::ir::{ItemMap, OpaqueItem, Static, Struct, Typedef, Union};
use bindgen::utilities::{SynAbiHelpers, SynItemHelpers};
const STD_CRATES: &'static [&'static str] = &["std",
"std_unicode",
"alloc",
"collections",
"core",
"proc_macro"];
const STD_CRATES: &'static [&'static str] = &[
"std",
"std_unicode",
"alloc",
"collections",
"core",
"proc_macro",
];
type ParseResult = Result<Parse, String>;
@ -55,11 +57,13 @@ pub fn parse_src(src_file: &Path) -> ParseResult {
/// Inside a crate, `mod` and `extern crate` declarations are followed
/// and parsed. To find an external crate, the parser uses the `cargo metadata`
/// command to find the location of dependencies.
pub(crate) fn parse_lib(lib: Cargo,
parse_deps: bool,
include: &Option<Vec<String>>,
exclude: &Vec<String>,
expand: &Vec<String>) -> ParseResult {
pub(crate) fn parse_lib(
lib: Cargo,
parse_deps: bool,
include: &Option<Vec<String>>,
exclude: &Vec<String>,
expand: &Vec<String>,
) -> ParseResult {
let mut context = Parser {
binding_crate_name: lib.binding_crate_name().to_owned(),
lib: Some(lib),
@ -121,8 +125,7 @@ impl Parser {
}
// Check the blacklist
return !STD_CRATES.contains(&pkg_name.as_ref()) &&
!self.exclude.contains(&pkg_name);
return !STD_CRATES.contains(&pkg_name.as_ref()) && !self.exclude.contains(&pkg_name);
}
fn parse_crate(&mut self, pkg: &PackageRef) -> Result<(), String> {
@ -138,14 +141,15 @@ impl Parser {
let crate_src = self.lib.as_ref().unwrap().find_crate_src(pkg);
match crate_src {
Some(crate_src) => {
self.parse_mod(pkg, crate_src.as_path())
},
Some(crate_src) => self.parse_mod(pkg, crate_src.as_path()),
None => {
// This should be an error, but is common enough to just elicit a warning
warn!("Parsing crate `{}`: can't find lib.rs with `cargo metadata`.", pkg.name);
warn!(
"Parsing crate `{}`: can't find lib.rs with `cargo metadata`.",
pkg.name
);
Ok(())
},
}
}
}
@ -155,7 +159,8 @@ impl Parser {
let mod_parsed = {
if !self.cache_expanded_crate.contains_key(&pkg.name) {
let s = self.lib.as_ref().unwrap().expand_crate(pkg)?;
let i = syn::parse_crate(&s).map_err(|msg| format!("Parsing crate `{}`:\n{}.", pkg.name, msg))?;
let i = syn::parse_crate(&s)
.map_err(|msg| format!("Parsing crate `{}`:\n{}.", pkg.name, msg))?;
self.cache_expanded_crate.insert(pkg.name.clone(), i.items);
}
@ -165,13 +170,17 @@ impl Parser {
self.process_expanded_mod(pkg, &mod_parsed)
}
fn process_expanded_mod(&mut self,
pkg: &PackageRef,
items: &Vec<syn::Item>) -> Result<(), String> {
self.out.load_syn_crate_mod(&self.binding_crate_name,
&pkg.name,
&Cfg::join(&self.cfg_stack),
items);
fn process_expanded_mod(
&mut self,
pkg: &PackageRef,
items: &Vec<syn::Item>,
) -> Result<(), String> {
self.out.load_syn_crate_mod(
&self.binding_crate_name,
&pkg.name,
&Cfg::join(&self.cfg_stack),
items,
);
for item in items {
match item.node {
@ -184,7 +193,11 @@ impl Parser {
if let &Some(ref inline_items) = inline_items {
self.process_expanded_mod(pkg, inline_items)?;
} else {
error!("Parsing crate `{}`: external mod found in expanded source, this shouldn't be possible.", pkg.name);
error!(
"Parsing crate `{}`: external mod found in expanded source, \
this shouldn't be possible.",
pkg.name
);
}
if cfg.is_some() {
@ -201,15 +214,26 @@ impl Parser {
if self.should_parse_dependency(&dep_pkg_name) {
if self.lib.is_some() {
let dep_pkg_ref = self.lib.as_ref().unwrap().find_dep_ref(pkg, &dep_pkg_name);
let dep_pkg_ref =
self.lib.as_ref().unwrap().find_dep_ref(pkg, &dep_pkg_name);
if let Some(dep_pkg_ref) = dep_pkg_ref {
self.parse_crate(&dep_pkg_ref)?;
} else {
error!("Parsing crate `{}`: can't find dependency version for `{}`.", pkg.name, dep_pkg_name);
error!(
"Parsing crate `{}`: can't find dependency version for `{}`.",
pkg.name,
dep_pkg_name
);
}
} else {
error!("Parsing crate `{}`: cannot parse external crate `{}` because cbindgen is in single source mode. Consider specifying a crate directory instead of a source file.", pkg.name, dep_pkg_name);
error!(
"Parsing crate `{}`: cannot parse external crate `{}` because \
cbindgen is in single source mode. Consider specifying a crate \
directory instead of a source file.",
pkg.name,
dep_pkg_name
);
}
}
@ -224,9 +248,7 @@ impl Parser {
Ok(())
}
fn parse_mod(&mut self,
pkg: &PackageRef,
mod_path: &Path) -> Result<(), String> {
fn parse_mod(&mut self, pkg: &PackageRef, mod_path: &Path) -> Result<(), String> {
let mod_parsed = {
let owned_mod_path = mod_path.to_path_buf();
@ -240,10 +262,24 @@ impl Parser {
}
let mut s = String::new();
let mut f = File::open(mod_path).map_err(|_| format!("Parsing crate `{}`: cannot open file `{:?}`.", pkg.name, mod_path))?;
f.read_to_string(&mut s).map_err(|_| format!("Parsing crate `{}`: cannot open file `{:?}`.", pkg.name, mod_path))?;
let mut f = File::open(mod_path).map_err(|_| {
format!(
"Parsing crate `{}`: cannot open file `{:?}`.",
pkg.name,
mod_path
)
})?;
f.read_to_string(&mut s).map_err(|_| {
format!(
"Parsing crate `{}`: cannot open file `{:?}`.",
pkg.name,
mod_path
)
})?;
let i = syn::parse_crate(&s).map_err(|msg| format!("Parsing crate `{}`:\n{}.", pkg.name, limit_string(&msg)))?;
let i = syn::parse_crate(&s).map_err(|msg| {
format!("Parsing crate `{}`:\n{}.", pkg.name, limit_string(&msg))
})?;
self.cache_src.insert(owned_mod_path.clone(), i.items);
}
@ -253,19 +289,21 @@ impl Parser {
let mod_dir = mod_path.parent().unwrap();
self.process_mod(pkg,
mod_dir,
&mod_parsed)
self.process_mod(pkg, mod_dir, &mod_parsed)
}
fn process_mod(&mut self,
pkg: &PackageRef,
mod_dir: &Path,
items: &Vec<syn::Item>) -> Result<(), String> {
self.out.load_syn_crate_mod(&self.binding_crate_name,
&pkg.name,
&Cfg::join(&self.cfg_stack),
items);
fn process_mod(
&mut self,
pkg: &PackageRef,
mod_dir: &Path,
items: &Vec<syn::Item>,
) -> Result<(), String> {
self.out.load_syn_crate_mod(
&self.binding_crate_name,
&pkg.name,
&Cfg::join(&self.cfg_stack),
items,
);
for item in items {
match item.node {
@ -278,22 +316,23 @@ impl Parser {
}
if let &Some(ref inline_items) = inline_items {
self.process_mod(pkg,
&mod_dir.join(&next_mod_name),
inline_items)?;
self.process_mod(pkg, &mod_dir.join(&next_mod_name), inline_items)?;
} else {
let next_mod_path1 = mod_dir.join(next_mod_name.clone() + ".rs");
let next_mod_path2 = mod_dir.join(next_mod_name.clone()).join("mod.rs");
if next_mod_path1.exists() {
self.parse_mod(pkg,
next_mod_path1.as_path())?;
self.parse_mod(pkg, next_mod_path1.as_path())?;
} else if next_mod_path2.exists() {
self.parse_mod(pkg,
next_mod_path2.as_path())?;
self.parse_mod(pkg, next_mod_path2.as_path())?;
} else {
// This should be an error, but is common enough to just elicit a warning
warn!("Parsing crate `{}`: can't find mod {}`.", pkg.name, next_mod_name);
// This should be an error, but it's common enough to
// just elicit a warning
warn!(
"Parsing crate `{}`: can't find mod {}`.",
pkg.name,
next_mod_name
);
}
}
@ -315,15 +354,26 @@ impl Parser {
if self.should_parse_dependency(&dep_pkg_name) {
if self.lib.is_some() {
let dep_pkg_ref = self.lib.as_ref().unwrap().find_dep_ref(pkg, &dep_pkg_name);
let dep_pkg_ref =
self.lib.as_ref().unwrap().find_dep_ref(pkg, &dep_pkg_name);
if let Some(dep_pkg_ref) = dep_pkg_ref {
self.parse_crate(&dep_pkg_ref)?;
} else {
error!("Parsing crate `{}`: can't find dependency version for `{}`.", pkg.name, dep_pkg_name);
error!(
"Parsing crate `{}`: can't find dependency version for `{}`.",
pkg.name,
dep_pkg_name
);
}
} else {
error!("Parsing crate `{}`: cannot parse external crate `{}` because cbindgen is in single source mode. Consider specifying a crate directory instead of a source file.", pkg.name, dep_pkg_name);
error!(
"Parsing crate `{}`: cannot parse external crate `{}` because \
cbindgen is in single source mode. Consider specifying a crate \
directory instead of a source file.",
pkg.name,
dep_pkg_name
);
}
}
@ -370,9 +420,7 @@ impl Parse {
self.opaque_items.try_insert(OpaqueItem {
name: name.to_owned(),
generic_params: GenericParams(
generic_params.iter()
.map(|x| (*x).to_owned())
.collect()
generic_params.iter().map(|x| (*x).to_owned()).collect(),
),
cfg: None,
annotations: AnnotationSet::new(),
@ -406,48 +454,40 @@ impl Parse {
self.functions.extend_from_slice(&other.functions);
}
pub fn load_syn_crate_mod(&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
items: &Vec<syn::Item>) {
pub fn load_syn_crate_mod(
&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
items: &Vec<syn::Item>,
) {
for item in items {
match item.node {
syn::ItemKind::ForeignMod(ref block) => {
self.load_syn_foreign_mod(binding_crate_name,
crate_name,
mod_cfg,
item,
block);
self.load_syn_foreign_mod(binding_crate_name, crate_name, mod_cfg, item, block);
}
syn::ItemKind::Fn(ref decl,
ref _unsafe,
ref _const,
ref abi,
ref _generic,
ref _block) => {
self.load_syn_fn(binding_crate_name,
crate_name,
mod_cfg,
item,
decl,
abi);
syn::ItemKind::Fn(
ref decl,
ref _unsafe,
ref _const,
ref abi,
ref _generic,
ref _block,
) => {
self.load_syn_fn(binding_crate_name, crate_name, mod_cfg, item, decl, abi);
}
syn::ItemKind::Const(ref ty, ref expr) => {
self.load_syn_const(binding_crate_name,
crate_name,
mod_cfg,
item,
ty,
expr);
self.load_syn_const(binding_crate_name, crate_name, mod_cfg, item, ty, expr);
}
syn::ItemKind::Static(ref ty, ref mutability, ref _expr) => {
self.load_syn_static(binding_crate_name,
crate_name,
mod_cfg,
item,
ty,
mutability);
self.load_syn_static(
binding_crate_name,
crate_name,
mod_cfg,
item,
ty,
mutability,
);
}
syn::ItemKind::Struct(ref variant, ref generics) => {
self.load_syn_struct(crate_name, mod_cfg, item, variant, generics);
@ -461,50 +501,61 @@ impl Parse {
syn::ItemKind::Ty(ref ty, ref generics) => {
self.load_syn_ty(crate_name, mod_cfg, item, ty, generics);
}
_ => { }
_ => {}
}
}
}
/// Enters a `extern "C" { }` declaration and loads function declarations.
fn load_syn_foreign_mod(&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
block: &syn::ForeignMod) {
fn load_syn_foreign_mod(
&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
block: &syn::ForeignMod,
) {
if !block.abi.is_c() {
info!("Skip {}::{} - (extern block must be extern C).", crate_name, &item.ident);
info!(
"Skip {}::{} - (extern block must be extern C).",
crate_name,
&item.ident
);
return;
}
for foreign_item in &block.items {
match foreign_item.node {
syn::ForeignItemKind::Fn(ref decl,
ref _generic) => {
syn::ForeignItemKind::Fn(ref decl, ref _generic) => {
if crate_name != binding_crate_name {
info!("Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name,
&foreign_item.ident);
info!(
"Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name,
&foreign_item.ident
);
return;
}
match Function::load(foreign_item.ident.to_string(),
decl,
true,
&foreign_item.attrs,
mod_cfg) {
match Function::load(
foreign_item.ident.to_string(),
decl,
true,
&foreign_item.attrs,
mod_cfg,
) {
Ok(func) => {
info!("Take {}::{}.", crate_name, &foreign_item.ident);
self.functions.push(func);
}
Err(msg) => {
error!("Cannot use fn {}::{} ({}).",
crate_name,
&foreign_item.ident,
msg);
},
error!(
"Cannot use fn {}::{} ({}).",
crate_name,
&foreign_item.ident,
msg
);
}
}
}
_ => {}
@ -513,251 +564,224 @@ impl Parse {
}
/// Loads a `fn` declaration
fn load_syn_fn(&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
decl: &syn::FnDecl,
abi: &Option<syn::Abi>) {
fn load_syn_fn(
&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
decl: &syn::FnDecl,
abi: &Option<syn::Abi>,
) {
if crate_name != binding_crate_name {
info!("Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name,
&item.ident);
info!(
"Skip {}::{} - (fn's outside of the binding crate are not used).",
crate_name,
&item.ident
);
return;
}
if item.is_no_mangle() && (abi.is_omitted() || abi.is_c()) {
match Function::load(item.ident.to_string(),
decl,
false,
&item.attrs,
mod_cfg) {
match Function::load(item.ident.to_string(), decl, false, &item.attrs, mod_cfg) {
Ok(func) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.functions.push(func);
}
Err(msg) => {
error!("Cannot use fn {}::{} ({}).",
crate_name,
&item.ident,
msg);
},
error!("Cannot use fn {}::{} ({}).", crate_name, &item.ident, msg);
}
}
} else {
if (abi.is_omitted() || abi.is_c()) && !item.is_no_mangle() {
warn!("Skip {}::{} - (`extern` but not `no_mangle`).",
crate_name,
&item.ident);
warn!(
"Skip {}::{} - (`extern` but not `no_mangle`).",
crate_name,
&item.ident
);
}
if abi.is_some() && !(abi.is_omitted() || abi.is_c()) {
warn!("Skip {}::{} - (non `extern \"C\"`).",
crate_name,
&item.ident);
warn!(
"Skip {}::{} - (non `extern \"C\"`).",
crate_name,
&item.ident
);
}
}
}
/// Loads a `const` declaration
fn load_syn_const(&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
ty: &syn::Ty,
expr: &syn::Expr) {
fn load_syn_const(
&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
ty: &syn::Ty,
expr: &syn::Expr,
) {
if crate_name != binding_crate_name {
info!("Skip {}::{} - (const's outside of the binding crate are not used).",
crate_name,
&item.ident);
info!(
"Skip {}::{} - (const's outside of the binding crate are not used).",
crate_name,
&item.ident
);
return;
}
let const_name = item.ident.to_string();
match Constant::load(const_name.clone(),
ty,
expr,
&item.attrs,
mod_cfg) {
match Constant::load(const_name.clone(), ty, expr, &item.attrs, mod_cfg) {
Ok(constant) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.constants.try_insert(constant);
}
Err(msg) => {
warn!("Skip {}::{} - ({})",
crate_name,
&item.ident,
msg);
warn!("Skip {}::{} - ({})", crate_name, &item.ident, msg);
}
}
}
/// Loads a `static` declaration
fn load_syn_static(&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
ty: &syn::Ty,
mutability: &syn::Mutability) {
fn load_syn_static(
&mut self,
binding_crate_name: &str,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
ty: &syn::Ty,
mutability: &syn::Mutability,
) {
if crate_name != binding_crate_name {
info!("Skip {}::{} - (static's outside of the binding crate are not used).",
crate_name,
&item.ident);
info!(
"Skip {}::{} - (static's outside of the binding crate are not used).",
crate_name,
&item.ident
);
return;
}
let static_name = item.ident.to_string();
match Static::load(static_name.clone(),
ty,
mutability,
&item.attrs,
mod_cfg) {
match Static::load(static_name.clone(), ty, mutability, &item.attrs, mod_cfg) {
Ok(constant) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.globals.try_insert(constant);
}
Err(msg) => {
warn!("Skip {}::{} - ({})",
crate_name,
&item.ident,
msg);
warn!("Skip {}::{} - ({})", crate_name, &item.ident, msg);
}
}
}
/// Loads a `struct` declaration
fn load_syn_struct(&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
variant: &syn::VariantData,
generics: &syn::Generics) {
fn load_syn_struct(
&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
variant: &syn::VariantData,
generics: &syn::Generics,
) {
let struct_name = item.ident.to_string();
match Struct::load(struct_name.clone(),
variant,
generics,
&item.attrs,
mod_cfg) {
match Struct::load(struct_name.clone(), variant, generics, &item.attrs, mod_cfg) {
Ok(st) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.structs.try_insert(st);
}
Err(msg) => {
info!("Take {}::{} - opaque ({}).",
crate_name,
&item.ident,
msg);
self.opaque_items.try_insert(OpaqueItem::new(struct_name,
generics,
&item.attrs,
mod_cfg));
info!("Take {}::{} - opaque ({}).", crate_name, &item.ident, msg);
self.opaque_items
.try_insert(OpaqueItem::new(struct_name, generics, &item.attrs, mod_cfg));
}
}
}
/// Loads a `union` declaration
fn load_syn_union(&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
variant: &syn::VariantData,
generics: &syn::Generics) {
fn load_syn_union(
&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
variant: &syn::VariantData,
generics: &syn::Generics,
) {
let union_name = item.ident.to_string();
match Union::load(union_name.clone(),
variant,
generics,
&item.attrs,
mod_cfg) {
match Union::load(union_name.clone(), variant, generics, &item.attrs, mod_cfg) {
Ok(st) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.unions.try_insert(st);
}
Err(msg) => {
info!("Take {}::{} - opaque ({}).",
crate_name,
&item.ident,
msg);
self.opaque_items.try_insert(OpaqueItem::new(union_name,
generics,
&item.attrs,
mod_cfg));
info!("Take {}::{} - opaque ({}).", crate_name, &item.ident, msg);
self.opaque_items
.try_insert(OpaqueItem::new(union_name, generics, &item.attrs, mod_cfg));
}
}
}
/// Loads a `enum` declaration
fn load_syn_enum(&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
variants: &Vec<syn::Variant>,
generics: &syn::Generics) {
if !generics.lifetimes.is_empty() ||
!generics.ty_params.is_empty() ||
!generics.where_clause.predicates.is_empty() {
info!("Skip {}::{} - (has generics or lifetimes or where bounds).",
crate_name,
&item.ident);
fn load_syn_enum(
&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
variants: &Vec<syn::Variant>,
generics: &syn::Generics,
) {
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty()
|| !generics.where_clause.predicates.is_empty()
{
info!(
"Skip {}::{} - (has generics or lifetimes or where bounds).",
crate_name,
&item.ident
);
return;
}
let enum_name = item.ident.to_string();
match Enum::load(enum_name.clone(),
variants,
&item.attrs,
mod_cfg) {
match Enum::load(enum_name.clone(), variants, &item.attrs, mod_cfg) {
Ok(en) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.enums.try_insert(en);
}
Err(msg) => {
info!("Take {}::{} - opaque ({}).", crate_name, &item.ident, msg);
self.opaque_items.try_insert(OpaqueItem::new(enum_name,
generics,
&item.attrs,
mod_cfg));
self.opaque_items
.try_insert(OpaqueItem::new(enum_name, generics, &item.attrs, mod_cfg));
}
}
}
/// Loads a `type` declaration
fn load_syn_ty(&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
ty: &syn::Ty,
generics: &syn::Generics) {
fn load_syn_ty(
&mut self,
crate_name: &str,
mod_cfg: &Option<Cfg>,
item: &syn::Item,
ty: &syn::Ty,
generics: &syn::Generics,
) {
let alias_name = item.ident.to_string();
match Typedef::load(alias_name.clone(),
ty,
generics,
&item.attrs,
mod_cfg) {
match Typedef::load(alias_name.clone(), ty, generics, &item.attrs, mod_cfg) {
Ok(st) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.typedefs.try_insert(st);
}
Err(msg) => {
info!("Take {}::{} - opaque ({}).",
crate_name,
&item.ident,
msg);
self.opaque_items.try_insert(OpaqueItem::new(alias_name,
generics,
&item.attrs,
mod_cfg));
info!("Take {}::{} - opaque ({}).", crate_name, &item.ident, msg);
self.opaque_items
.try_insert(OpaqueItem::new(alias_name, generics, &item.attrs, mod_cfg));
}
}
}

View File

@ -31,7 +31,7 @@ impl<'a> IdentifierType<'a> {
pub enum RenameRule {
/// Do not apply any renaming. The default.
None,
/// Converts the identifier to PascalCase and adds a prefix based on where the identifier is used.
/// Converts the identifier to PascalCase and adds a context dependent prefix
GeckoCase,
/// Converts the identifier to lower case.
LowerCase,
@ -63,9 +63,7 @@ impl RenameRule {
RenameRule::LowerCase => text.to_lowercase(),
RenameRule::UpperCase => text.to_uppercase(),
RenameRule::PascalCase => text.to_owned(),
RenameRule::CamelCase => {
text[..1].to_lowercase() + &text[1..]
}
RenameRule::CamelCase => text[..1].to_lowercase() + &text[1..],
RenameRule::SnakeCase => {
let mut result = String::new();
for (i, c) in text.char_indices() {
@ -96,14 +94,14 @@ impl RenameRule {
if let IdentifierType::EnumVariant(e) = context {
if let &RenameRule::QualifiedScreamingSnakeCase = self {
result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
&e.name, IdentifierType::Enum));
result.push_str(&RenameRule::ScreamingSnakeCase
.apply_to_pascal_case(&e.name, IdentifierType::Enum));
result.push_str("_");
}
}
result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_pascal_case(
&text, context));
result.push_str(&RenameRule::ScreamingSnakeCase
.apply_to_pascal_case(&text, context));
result
}
}
@ -122,8 +120,8 @@ impl RenameRule {
text = &text[1..];
}
context.to_str().to_owned() +
&RenameRule::PascalCase.apply_to_snake_case(text, context)
context.to_str().to_owned()
+ &RenameRule::PascalCase.apply_to_snake_case(text, context)
}
RenameRule::LowerCase => text.to_lowercase(),
RenameRule::UpperCase => text.to_uppercase(),
@ -175,14 +173,14 @@ impl RenameRule {
if let IdentifierType::EnumVariant(e) = context {
if let &RenameRule::QualifiedScreamingSnakeCase = self {
result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
&e.name, IdentifierType::Enum));
result.push_str(&RenameRule::ScreamingSnakeCase
.apply_to_snake_case(&e.name, IdentifierType::Enum));
result.push_str("_");
}
}
result.push_str(&RenameRule::ScreamingSnakeCase.apply_to_snake_case(
&text, context));
result.push_str(&RenameRule::ScreamingSnakeCase
.apply_to_snake_case(&text, context));
result
}
}

View File

@ -4,14 +4,19 @@
use syn;
pub trait IterHelpers : Iterator {
pub trait IterHelpers: Iterator {
fn try_skip_map<F, T, E>(&mut self, f: F) -> Result<Vec<T>, E>
where F: FnMut(&Self::Item) -> Result<Option<T>, E>;
where
F: FnMut(&Self::Item) -> Result<Option<T>, E>;
}
impl<I> IterHelpers for I where I: Iterator {
impl<I> IterHelpers for I
where
I: Iterator,
{
fn try_skip_map<F, T, E>(&mut self, mut f: F) -> Result<Vec<T>, E>
where F: FnMut(&Self::Item) -> Result<Option<T>, E>
where
F: FnMut(&Self::Item) -> Result<Option<T>, E>,
{
let mut out = Vec::new();
while let Some(item) = self.next() {
@ -42,33 +47,33 @@ pub trait SynItemHelpers {
impl SynItemHelpers for syn::Item {
fn has_attr(&self, target: syn::MetaItem) -> bool {
return self.attrs
.iter()
.any(|ref attr| attr.style == syn::AttrStyle::Outer && attr.value == target);
return self.attrs.iter().any(|ref attr| {
attr.style == syn::AttrStyle::Outer && attr.value == target
});
}
}
impl SynItemHelpers for syn::ForeignItem {
fn has_attr(&self, target: syn::MetaItem) -> bool {
return self.attrs
.iter()
.any(|ref attr| attr.style == syn::AttrStyle::Outer && attr.value == target);
return self.attrs.iter().any(|ref attr| {
attr.style == syn::AttrStyle::Outer && attr.value == target
});
}
}
impl SynItemHelpers for syn::Variant {
fn has_attr(&self, target: syn::MetaItem) -> bool {
return self.attrs
.iter()
.any(|ref attr| attr.style == syn::AttrStyle::Outer && attr.value == target);
return self.attrs.iter().any(|ref attr| {
attr.style == syn::AttrStyle::Outer && attr.value == target
});
}
}
impl SynItemHelpers for syn::Field {
fn has_attr(&self, target: syn::MetaItem) -> bool {
return self.attrs
.iter()
.any(|ref attr| attr.style == syn::AttrStyle::Outer && attr.value == target);
return self.attrs.iter().any(|ref attr| {
attr.style == syn::AttrStyle::Outer && attr.value == target
});
}
}

View File

@ -6,7 +6,7 @@ use std::cmp;
use std::io;
use std::io::Write;
use bindgen::config::{Config, Braces};
use bindgen::config::{Braces, Config};
/// A type of way to format a list.
pub enum ListType<'a> {
@ -84,7 +84,8 @@ impl<'a, F: Write> SourceWriter<'a, F> {
/// Takes a function that writes source and returns the maximum line length
/// written.
pub fn measure<T>(&self, func: T) -> usize
where T: Fn(&mut MeasureWriter)
where
T: Fn(&mut MeasureWriter),
{
let mut measurer = SourceWriter {
out: NullFile,
@ -118,9 +119,8 @@ impl<'a, F: Write> SourceWriter<'a, F> {
}
pub fn push_tab(&mut self) {
let spaces = self.spaces() -
(self.spaces() % self.config.tab_width) +
self.config.tab_width;
let spaces =
self.spaces() - (self.spaces() % self.config.tab_width) + self.config.tab_width;
self.spaces.push(spaces);
}
@ -176,16 +176,18 @@ impl<'a, F: Write> SourceWriter<'a, F> {
InnerWriter(self).write_fmt(fmt).unwrap();
}
pub fn write_horizontal_source_list<'b, S: Source>(&mut self, items: &Vec<S>, list_type: ListType<'b>) {
pub fn write_horizontal_source_list<'b, S: Source>(
&mut self,
items: &Vec<S>,
list_type: ListType<'b>,
) {
for (i, ref item) in items.iter().enumerate() {
item.write(self.config, self);
match list_type {
ListType::Join(text) => {
if i != items.len() - 1 {
write!(self, "{}", text);
}
}
ListType::Join(text) => if i != items.len() - 1 {
write!(self, "{}", text);
},
ListType::Cap(text) => {
write!(self, "{}", text);
}
@ -193,18 +195,20 @@ impl<'a, F: Write> SourceWriter<'a, F> {
}
}
pub fn write_vertical_source_list<'b, S: Source>(&mut self, items: &Vec<S>, list_type: ListType<'b>) {
pub fn write_vertical_source_list<'b, S: Source>(
&mut self,
items: &Vec<S>,
list_type: ListType<'b>,
) {
let align_length = self.line_length_for_align();
self.push_set_spaces(align_length);
for (i, ref item) in items.iter().enumerate() {
item.write(self.config, self);
match list_type {
ListType::Join(text) => {
if i != items.len() - 1 {
write!(self, "{}", text);
}
}
ListType::Join(text) => if i != items.len() - 1 {
write!(self, "{}", text);
},
ListType::Cap(text) => {
write!(self, "{}", text);
}

View File

@ -27,8 +27,12 @@ pub fn generate<P: AsRef<Path>>(crate_dir: P) -> Result<Bindings, String> {
/// A utility function for build scripts to generate bindings for a crate with a
/// custom config.
pub fn generate_with_config<P: AsRef<Path>>(crate_dir: P, config: Config) -> Result<Bindings, String> {
Builder::new().with_config(config)
.with_crate(crate_dir)
.generate()
pub fn generate_with_config<P: AsRef<Path>>(
crate_dir: P,
config: Config,
) -> Result<Bindings, String> {
Builder::new()
.with_config(config)
.with_crate(crate_dir)
.generate()
}

View File

@ -27,10 +27,7 @@ impl log::Log for TraceLogger {
fn log(&self, record: &LogRecord) {
if self.enabled(record.metadata()) {
writeln!(io::stderr(),
"{}: {}",
record.level(),
record.args()).unwrap();
writeln!(io::stderr(), "{}: {}", record.level(), record.args()).unwrap();
}
}
}
@ -50,10 +47,7 @@ impl log::Log for WarnLogger {
fn log(&self, record: &LogRecord) {
if self.enabled(record.metadata()) {
writeln!(io::stderr(),
"{}: {}",
record.level(),
record.args()).unwrap();
writeln!(io::stderr(), "{}: {}", record.level(), record.args()).unwrap();
}
}
}
@ -73,10 +67,7 @@ impl log::Log for InfoLogger {
fn log(&self, record: &LogRecord) {
if self.enabled(record.metadata()) {
writeln!(io::stderr(),
"{}: {}",
record.level(),
record.args()).unwrap();
writeln!(io::stderr(), "{}: {}", record.level(), record.args()).unwrap();
}
}
}

View File

@ -16,7 +16,7 @@ extern crate serde_json;
extern crate syn;
extern crate toml;
use clap::{Arg, ArgMatches, App};
use clap::{App, Arg, ArgMatches};
mod logging;
mod bindgen;
@ -28,10 +28,10 @@ fn apply_config_overrides<'a>(config: &mut Config, matches: &ArgMatches<'a>) {
// used by compile-tests.
if let Some(lang) = matches.value_of("lang") {
config.language = match lang {
"C++"=> Language::Cxx,
"c++"=> Language::Cxx,
"C"=> Language::C,
"c"=> Language::C,
"C++" => Language::Cxx,
"c++" => Language::Cxx,
"C" => Language::C,
"c" => Language::C,
_ => {
error!("Unknown language specified.");
return;
@ -55,15 +55,14 @@ fn load_bindings<'a>(input: &Path, matches: &ArgMatches<'a>) -> Result<Bindings,
apply_config_overrides(&mut config, &matches);
return Builder::new().with_config(config)
.with_src(input)
.generate();
return Builder::new()
.with_config(config)
.with_src(input)
.generate();
}
// We have to load a whole crate, so we use cargo to gather metadata
let lib = Cargo::load(input,
matches.value_of("crate"),
true)?;
let lib = Cargo::load(input, matches.value_of("crate"), true)?;
// Load any config specified or search in the binding crate directory
let mut config = match matches.value_of("config") {
@ -82,50 +81,68 @@ fn load_bindings<'a>(input: &Path, matches: &ArgMatches<'a>) -> Result<Bindings,
apply_config_overrides(&mut config, &matches);
Builder::new().with_config(config)
.with_cargo(lib)
.generate()
Builder::new()
.with_config(config)
.with_cargo(lib)
.generate()
}
fn main() {
let matches = App::new("cbindgen")
.version(bindgen::VERSION)
.about("Generate C bindings for a Rust library")
.arg(Arg::with_name("v")
.short("v")
.multiple(true)
.help("Enable verbose logging"))
.arg(Arg::with_name("config")
.short("c")
.long("config")
.value_name("PATH")
.help("Specify path to a `cbindgen.toml` config to use"))
.arg(Arg::with_name("lang")
.short("l")
.long("lang")
.value_name("LANGUAGE")
.help("Specify the language to output bindings in")
.possible_values(&["c++", "C++", "c", "C"]))
.arg(Arg::with_name("d")
.short("d")
.long("parse-dependencies")
.help("Whether to parse dependencies when generating bindings"))
.arg(Arg::with_name("INPUT")
.help("A crate directory or source file to generate bindings for")
.required(false)
.index(1))
.arg(Arg::with_name("crate")
.long("crate")
.value_name("CRATE_NAME")
.help("If generating bindings for a crate, the specific crate to generate bindings for")
.required(false))
.arg(Arg::with_name("out")
.short("o")
.long("output")
.value_name("PATH")
.help("The file to output the bindings to")
.required(false))
.get_matches();
.version(bindgen::VERSION)
.about("Generate C bindings for a Rust library")
.arg(
Arg::with_name("v")
.short("v")
.multiple(true)
.help("Enable verbose logging"),
)
.arg(
Arg::with_name("config")
.short("c")
.long("config")
.value_name("PATH")
.help("Specify path to a `cbindgen.toml` config to use"),
)
.arg(
Arg::with_name("lang")
.short("l")
.long("lang")
.value_name("LANGUAGE")
.help("Specify the language to output bindings in")
.possible_values(&["c++", "C++", "c", "C"]),
)
.arg(
Arg::with_name("d")
.short("d")
.long("parse-dependencies")
.help("Whether to parse dependencies when generating bindings"),
)
.arg(
Arg::with_name("INPUT")
.help("A crate directory or source file to generate bindings for")
.required(false)
.index(1),
)
.arg(
Arg::with_name("crate")
.long("crate")
.value_name("CRATE_NAME")
.help(
"If generating bindings for a crate, \
the specific crate to generate bindings for",
)
.required(false),
)
.arg(
Arg::with_name("out")
.short("o")
.long("output")
.value_name("PATH")
.help("The file to output the bindings to")
.required(false),
)
.get_matches();
// Initialize logging
match matches.occurrences_of("v") {