diff options
author | Daniel Brooks <db48x@db48x.net> | 2018-06-04 10:04:02 -0700 |
---|---|---|
committer | Daniel Brooks <db48x@db48x.net> | 2018-06-04 10:06:33 -0700 |
commit | 3a8df51056f392036c223d1fbc213d069dfa9124 (patch) | |
tree | 69279ce28baa193df0d3e4ccd689f9ea4e29fdd4 | |
parent | 440374102538f05eb4208fd0bef1db9214a4d48a (diff) |
add --constified-enum to output consts when the default is changed
-rw-r--r-- | src/codegen/mod.rs | 2 | ||||
-rw-r--r-- | src/ir/enum_ty.rs | 47 | ||||
-rw-r--r-- | src/lib.rs | 26 | ||||
-rw-r--r-- | src/options.rs | 21 | ||||
-rw-r--r-- | tests/expectations/tests/enum-undefault.rs | 13 | ||||
-rw-r--r-- | tests/headers/enum-undefault.h | 11 |
6 files changed, 89 insertions, 31 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 387ff495..1d35f8fb 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2520,6 +2520,8 @@ impl CodeGenerator for Enum { EnumVariation::Bitfield } else if self.is_rustified_enum(ctx, item) { EnumVariation::Rust + } else if self.is_constified_enum(ctx, item) { + EnumVariation::Consts } else { ctx.options().default_enum_style }; diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index 4ae311e2..ee705f16 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -7,6 +7,7 @@ use clang; use ir::annotations::Annotations; use ir::item::ItemCanonicalPath; use parse::{ClangItemParser, ParseError}; +use regex_set::RegexSet; /// An enum representing custom handling that can be given to a variant. #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -137,44 +138,36 @@ impl Enum { Ok(Enum::new(repr, variants)) } - /// Whether the enum should be a bitfield - pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool { + fn is_matching_enum(&self, ctx: &BindgenContext, enums: &RegexSet, item: &Item) -> bool { let path = item.canonical_path(ctx); let enum_ty = item.expect_type(); - ctx.options().bitfield_enums.matches(&path[1..].join("::")) || - (enum_ty.name().is_none() && - self.variants().iter().any(|v| { - ctx.options().bitfield_enums.matches(&v.name()) - })) + let path_matches = enums.matches(&path[1..].join("::")); + let enum_is_anon = enum_ty.name().is_none(); + let a_variant_matches = self.variants().iter().any(|v| { + enums.matches(&v.name()) + }); + path_matches || (enum_is_anon && a_variant_matches) + } + + /// Whether the enum should be a bitfield + pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool { + self.is_matching_enum(ctx, &ctx.options().bitfield_enums, item) } /// Whether the enum should be an constified enum module - pub fn is_constified_enum_module( - &self, - ctx: &BindgenContext, - item: &Item, - ) -> bool { - let path = item.canonical_path(ctx); - let enum_ty = item.expect_type(); + pub fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool { + self.is_matching_enum(ctx, &ctx.options().constified_enum_modules, item) + } - ctx.options().constified_enum_modules.matches(&path[1..].join("::")) || - (enum_ty.name().is_none() && - self.variants().iter().any(|v| { - ctx.options().constified_enum_modules.matches(&v.name()) - })) + /// Whether the enum should be an set of constants + pub fn is_constified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool { + self.is_matching_enum(ctx, &ctx.options().constified_enums, item) } /// Whether the enum should be a Rust enum pub fn is_rustified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool { - let path = item.canonical_path(ctx); - let enum_ty = item.expect_type(); - - ctx.options().rustified_enums.matches(&path[1..].join("::")) || - (enum_ty.name().is_none() && - self.variants().iter().any(|v| { - ctx.options().rustified_enums.matches(&v.name()) - })) + self.is_matching_enum(ctx, &ctx.options().rustified_enums, item) } } @@ -257,6 +257,20 @@ impl Builder { .count(); self.options + .constified_enums + .get_items() + .iter() + .map(|item| { + output_vector.push("--constified-enum".into()); + output_vector.push( + item.trim_left_matches("^") + .trim_right_matches("$") + .into(), + ); + }) + .count(); + + self.options .blacklisted_types .get_items() .iter() @@ -772,6 +786,13 @@ impl Builder { } /// Mark the given enum (or set of enums, if using a pattern) as a set of + /// constants that are not to be put into a module. + pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.constified_enums.insert(arg); + self + } + + /// Mark the given enum (or set of enums, if using a pattern) as a set of /// constants that should be put into a module. /// /// This makes bindgen generate modules containing constants instead of @@ -1268,6 +1289,9 @@ struct BindgenOptions { /// The enum patterns to mark an enum as a module of constants. constified_enum_modules: RegexSet, + /// The enum patterns to mark an enum as a set of constants. + constified_enums: RegexSet, + /// Whether we should generate builtins or not. builtins: bool, @@ -1443,6 +1467,7 @@ impl BindgenOptions { self.blacklisted_types.build(); self.opaque_types.build(); self.bitfield_enums.build(); + self.constified_enums.build(); self.constified_enum_modules.build(); self.rustified_enums.build(); self.no_partialeq_types.build(); @@ -1480,6 +1505,7 @@ impl Default for BindgenOptions { default_enum_style: Default::default(), bitfield_enums: Default::default(), rustified_enums: Default::default(), + constified_enums: Default::default(), constified_enum_modules: Default::default(), builtins: false, emit_ast: false, diff --git a/src/options.rs b/src/options.rs index 97b2556b..5169fb9a 100644 --- a/src/options.rs +++ b/src/options.rs @@ -36,15 +36,22 @@ where Arg::with_name("bitfield-enum") .long("bitfield-enum") .help("Mark any enum whose name matches <regex> as a set of \ - bitfield flags instead of an enumeration.") + bitfield flags.") .value_name("regex") .takes_value(true) .multiple(true) .number_of_values(1), Arg::with_name("rustified-enum") .long("rustified-enum") - .help("Mark any enum whose name matches <regex> as a Rust enum \ - instead of a set of constants.") + .help("Mark any enum whose name matches <regex> as a Rust enum.") + .value_name("regex") + .takes_value(true) + .multiple(true) + .number_of_values(1), + Arg::with_name("constified-enum") + .long("constified-enum") + .help("Mark any enum whose name matches <regex> as a series of \ + constants.") .value_name("regex") .takes_value(true) .multiple(true) @@ -52,7 +59,7 @@ where Arg::with_name("constified-enum-module") .long("constified-enum-module") .help("Mark any enum whose name matches <regex> as a module of \ - constants instead of just constants.") + constants.") .value_name("regex") .takes_value(true) .multiple(true) @@ -326,6 +333,12 @@ where } } + if let Some(bitfields) = matches.values_of("constified-enum") { + for regex in bitfields { + builder = builder.constified_enum(regex); + } + } + if let Some(constified_mods) = matches.values_of("constified-enum-module") { for regex in constified_mods { builder = builder.constified_enum_module(regex); diff --git a/tests/expectations/tests/enum-undefault.rs b/tests/expectations/tests/enum-undefault.rs new file mode 100644 index 00000000..b5d56c42 --- /dev/null +++ b/tests/expectations/tests/enum-undefault.rs @@ -0,0 +1,13 @@ +/* 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 const Neg_MinusOne: Neg = -1; +pub const Neg_One: Neg = 1; +pub type Neg = i32; diff --git a/tests/headers/enum-undefault.h b/tests/headers/enum-undefault.h new file mode 100644 index 00000000..7150be0d --- /dev/null +++ b/tests/headers/enum-undefault.h @@ -0,0 +1,11 @@ +// bindgen-flags: --default-enum-style=rust --constified-enum=Neg + +enum Foo { + Bar = 0, + Qux +}; + +enum Neg { + MinusOne = -1, + One = 1, +}; |