Format with rustfmt-nightly
This commit is contained in:
parent
ce60054f8d
commit
58d3178dc5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 ");
|
||||
}
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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());
|
||||
|
@ -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"))),
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
12
src/lib.rs
12
src/lib.rs
@ -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()
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
119
src/main.rs
119
src/main.rs
@ -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") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user