Skip to content

add --constified-enum to output consts when the default is changed #1329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
47 changes: 20 additions & 27 deletions src/ir/enum_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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)
}
}

Expand Down
26 changes: 26 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,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()
Expand Down Expand Up @@ -771,6 +785,13 @@ impl Builder {
self
}

/// 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.
///
Expand Down Expand Up @@ -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,

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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,
Expand Down
21 changes: 17 additions & 4 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,30 @@ 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)
.number_of_values(1),
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)
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions tests/expectations/tests/enum-undefault.rs
Original file line number Diff line number Diff line change
@@ -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;
11 changes: 11 additions & 0 deletions tests/headers/enum-undefault.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// bindgen-flags: --default-enum-style=rust --constified-enum=Neg

enum Foo {
Bar = 0,
Qux
};

enum Neg {
MinusOne = -1,
One = 1,
};