summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Brooks <db48x@db48x.net>2018-06-03 11:35:07 -0700
committerDaniel Brooks <db48x@db48x.net>2018-06-03 11:35:07 -0700
commit0b293e1f6d9b26fb8dcc5113c3f04c47b588d04f (patch)
tree430f785efda556a507cb53c038be605b97d3449f
parentcfd0fa5e559327006d6fbc1e37357a2981aba224 (diff)
Add an option to set the default codegen style for all enums
-rw-r--r--src/codegen/mod.rs37
-rw-r--r--src/lib.rs21
-rw-r--r--src/options.rs13
-rw-r--r--tests/expectations/tests/bitfield-32bit-overflow.rs2
-rw-r--r--tests/expectations/tests/bitfield_align.rs2
-rw-r--r--tests/expectations/tests/enum-default-bitfield.rs44
-rw-r--r--tests/expectations/tests/enum-default-consts.rs12
-rw-r--r--tests/expectations/tests/enum-default-module.rs14
-rw-r--r--tests/expectations/tests/enum-default-rust.rs15
-rw-r--r--tests/expectations/tests/issue-739-pointer-wide-bitfield.rs2
-rw-r--r--tests/expectations/tests/struct_with_bitfields.rs2
-rw-r--r--tests/headers/enum-default-bitfield.h11
-rw-r--r--tests/headers/enum-default-consts.h11
-rw-r--r--tests/headers/enum-default-module.h11
-rw-r--r--tests/headers/enum-default-rust.h11
15 files changed, 195 insertions, 13 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index b6aabb17..4575f9b2 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -40,6 +40,7 @@ use ir::var::Var;
use quote;
use proc_macro2::{self, Term, Span};
+use std;
use std::borrow::Cow;
use std::cell::Cell;
use std::collections::{HashSet, VecDeque};
@@ -2103,11 +2104,15 @@ impl MethodCodegen for Method {
}
/// A helper type that represents different enum variations.
-#[derive(Copy, Clone)]
-enum EnumVariation {
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum EnumVariation {
+ /// The code for this enum will use a Rust enum
Rust,
+ /// The code for this enum will use a bitfield
Bitfield,
+ /// The code for this enum will use consts
Consts,
+ /// The code for this enum will use a module containing consts
ModuleConsts
}
@@ -2136,6 +2141,31 @@ impl EnumVariation {
}
}
+impl Default for EnumVariation {
+ fn default() -> EnumVariation {
+ EnumVariation::Consts
+ }
+}
+
+impl std::str::FromStr for EnumVariation {
+ type Err = std::io::Error;
+
+ /// Create a `EnumVariation` from a string.
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s.as_ref() {
+ "rust" => Ok(EnumVariation::Rust),
+ "bitfield" => Ok(EnumVariation::Bitfield),
+ "consts" => Ok(EnumVariation::Consts),
+ "moduleconsts" => Ok(EnumVariation::ModuleConsts),
+ _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,
+ concat!("Got an invalid EnumVariation. Accepted values ",
+ "are 'rust', 'bitfield', 'consts', and ",
+ "'moduleconsts'."))),
+ }
+ }
+}
+
+
/// A helper type to construct different enum variations.
enum EnumBuilder<'a> {
Rust {
@@ -2491,8 +2521,7 @@ impl CodeGenerator for Enum {
} else if self.is_rustified_enum(ctx, item) {
EnumVariation::Rust
} else {
- // We generate consts by default
- EnumVariation::Consts
+ ctx.options().default_enum_variant
};
let mut attrs = vec![];
diff --git a/src/lib.rs b/src/lib.rs
index 9f90ffb7..38b91494 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -83,6 +83,7 @@ use ir::context::{BindgenContext, ItemId};
use ir::item::Item;
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;
+pub use codegen::EnumVariation;
use std::borrow::Cow;
use std::collections::HashMap;
@@ -203,6 +204,16 @@ impl Builder {
output_vector.push("--rust-target".into());
output_vector.push(self.options.rust_target.into());
+ if self.options.default_enum_variant != Default::default() {
+ output_vector.push("--default-enum-variant=".into());
+ output_vector.push(match self.options.default_enum_variant {
+ codegen::EnumVariation::Rust => "rust",
+ codegen::EnumVariation::Bitfield => "bitfield",
+ codegen::EnumVariation::Consts => "consts",
+ codegen::EnumVariation::ModuleConsts => "moduleconsts",
+ }.into())
+ };
+
self.options
.bitfield_enums
.get_items()
@@ -730,6 +741,12 @@ impl Builder {
}
+ /// Set the default type of code to generate for enums
+ pub fn default_enum_variant(mut self, arg: codegen::EnumVariation) -> Builder {
+ self.options.default_enum_variant = arg;
+ self
+ }
+
/// Mark the given enum (or set of enums, if using a pattern) as being
/// bitfield-like. Regular expressions are supported.
///
@@ -1240,6 +1257,9 @@ struct BindgenOptions {
/// Whitelisted variables. See docs for `whitelisted_types` for more.
whitelisted_vars: RegexSet,
+ /// The default type of code to generate for enums
+ default_enum_variant: codegen::EnumVariation,
+
/// The enum patterns to mark an enum as bitfield.
bitfield_enums: RegexSet,
@@ -1458,6 +1478,7 @@ impl Default for BindgenOptions {
whitelisted_types: Default::default(),
whitelisted_functions: Default::default(),
whitelisted_vars: Default::default(),
+ default_enum_variant: Default::default(),
bitfield_enums: Default::default(),
rustified_enums: Default::default(),
constified_enum_modules: Default::default(),
diff --git a/src/options.rs b/src/options.rs
index b3ddbbfd..9405aff9 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -1,4 +1,4 @@
-use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder};
+use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder, EnumVariation};
use clap::{App, Arg};
use std::fs::File;
use std::io::{self, Error, ErrorKind, Write, stderr};
@@ -26,6 +26,13 @@ where
Arg::with_name("header")
.help("C or C++ header file")
.required(true),
+ Arg::with_name("default-enum-variant")
+ .long("default-enum-variant")
+ .help("choose one")
+ .value_name("variant")
+ .default_value("consts")
+ .possible_values(&["consts", "moduleconsts", "bitfield", "rust"])
+ .multiple(false),
Arg::with_name("bitfield-enum")
.long("bitfield-enum")
.help("Mark any enum whose name matches <regex> as a set of \
@@ -303,6 +310,10 @@ where
builder = builder.rust_target(RustTarget::from_str(rust_target)?);
}
+ if let Some(variant) = matches.value_of("default-enum-variant") {
+ builder = builder.default_enum_variant(EnumVariation::from_str(variant)?)
+ }
+
if let Some(bitfields) = matches.values_of("bitfield-enum") {
for regex in bitfields {
builder = builder.bitfield_enum(regex);
diff --git a/tests/expectations/tests/bitfield-32bit-overflow.rs b/tests/expectations/tests/bitfield-32bit-overflow.rs
index f64299a6..7270649e 100644
--- a/tests/expectations/tests/bitfield-32bit-overflow.rs
+++ b/tests/expectations/tests/bitfield-32bit-overflow.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
diff --git a/tests/expectations/tests/bitfield_align.rs b/tests/expectations/tests/bitfield_align.rs
index d7ee0445..9821aa6f 100644
--- a/tests/expectations/tests/bitfield_align.rs
+++ b/tests/expectations/tests/bitfield_align.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
diff --git a/tests/expectations/tests/enum-default-bitfield.rs b/tests/expectations/tests/enum-default-bitfield.rs
new file mode 100644
index 00000000..19172d0b
--- /dev/null
+++ b/tests/expectations/tests/enum-default-bitfield.rs
@@ -0,0 +1,44 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+impl Foo {
+ pub const Bar: Foo = Foo(0);
+}
+impl Foo {
+ pub const Qux: Foo = Foo(1);
+}
+impl ::std::ops::BitOr<Foo> for Foo {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ Foo(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for Foo {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: Foo) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<Foo> for Foo {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ Foo(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for Foo {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: Foo) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Foo(pub u32);
+pub mod Neg {
+ pub type Type = i32;
+ pub const MinusOne: Type = -1;
+ pub const One: Type = 1;
+}
diff --git a/tests/expectations/tests/enum-default-consts.rs b/tests/expectations/tests/enum-default-consts.rs
new file mode 100644
index 00000000..6ced4de0
--- /dev/null
+++ b/tests/expectations/tests/enum-default-consts.rs
@@ -0,0 +1,12 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub const Foo_Bar: Foo = 0;
+pub const Foo_Qux: Foo = 1;
+pub type Foo = u32;
+pub mod Neg {
+ pub type Type = i32;
+ pub const MinusOne: Type = -1;
+ pub const One: Type = 1;
+}
diff --git a/tests/expectations/tests/enum-default-module.rs b/tests/expectations/tests/enum-default-module.rs
new file mode 100644
index 00000000..953793c3
--- /dev/null
+++ b/tests/expectations/tests/enum-default-module.rs
@@ -0,0 +1,14 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub mod Foo {
+ pub type Type = u32;
+ pub const Bar: Type = 0;
+ pub const Qux: Type = 1;
+}
+pub mod Neg {
+ pub type Type = i32;
+ pub const MinusOne: Type = -1;
+ pub const One: Type = 1;
+}
diff --git a/tests/expectations/tests/enum-default-rust.rs b/tests/expectations/tests/enum-default-rust.rs
new file mode 100644
index 00000000..1400e373
--- /dev/null
+++ b/tests/expectations/tests/enum-default-rust.rs
@@ -0,0 +1,15 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum Foo {
+ Bar = 0,
+ Qux = 1,
+}
+pub mod Neg {
+ pub type Type = i32;
+ pub const MinusOne: Type = -1;
+ pub const One: Type = 1;
+}
diff --git a/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs b/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs
index 806b3f16..81c32bbf 100644
--- a/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs
+++ b/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
diff --git a/tests/expectations/tests/struct_with_bitfields.rs b/tests/expectations/tests/struct_with_bitfields.rs
index 85f37e10..a45472d5 100644
--- a/tests/expectations/tests/struct_with_bitfields.rs
+++ b/tests/expectations/tests/struct_with_bitfields.rs
@@ -1,9 +1,7 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
diff --git a/tests/headers/enum-default-bitfield.h b/tests/headers/enum-default-bitfield.h
new file mode 100644
index 00000000..a73f2838
--- /dev/null
+++ b/tests/headers/enum-default-bitfield.h
@@ -0,0 +1,11 @@
+// bindgen-flags: --default-enum-variant=bitfield --constified-enum-module=Neg
+
+enum Foo {
+ Bar = 0,
+ Qux
+};
+
+enum Neg {
+ MinusOne = -1,
+ One = 1,
+};
diff --git a/tests/headers/enum-default-consts.h b/tests/headers/enum-default-consts.h
new file mode 100644
index 00000000..17f0afc4
--- /dev/null
+++ b/tests/headers/enum-default-consts.h
@@ -0,0 +1,11 @@
+// bindgen-flags: --default-enum-variant=consts --constified-enum-module=Neg
+
+enum Foo {
+ Bar = 0,
+ Qux
+};
+
+enum Neg {
+ MinusOne = -1,
+ One = 1,
+};
diff --git a/tests/headers/enum-default-module.h b/tests/headers/enum-default-module.h
new file mode 100644
index 00000000..e586cca2
--- /dev/null
+++ b/tests/headers/enum-default-module.h
@@ -0,0 +1,11 @@
+// bindgen-flags: --default-enum-variant=moduleconsts --constified-enum-module=Neg
+
+enum Foo {
+ Bar = 0,
+ Qux
+};
+
+enum Neg {
+ MinusOne = -1,
+ One = 1,
+};
diff --git a/tests/headers/enum-default-rust.h b/tests/headers/enum-default-rust.h
new file mode 100644
index 00000000..797863c3
--- /dev/null
+++ b/tests/headers/enum-default-rust.h
@@ -0,0 +1,11 @@
+// bindgen-flags: --default-enum-variant=rust --constified-enum-module=Neg
+
+enum Foo {
+ Bar = 0,
+ Qux
+};
+
+enum Neg {
+ MinusOne = -1,
+ One = 1,
+};