diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen/mod.rs | 44 | ||||
-rw-r--r-- | src/ir/var.rs | 12 | ||||
-rw-r--r-- | src/lib.rs | 21 | ||||
-rw-r--r-- | src/options.rs | 17 |
4 files changed, 87 insertions, 7 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 203da256..de46bb22 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3048,6 +3048,50 @@ impl CodeGenerator for Enum { } } +/// Enum for the default type of macro constants. +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum MacroTypeVariation { + /// Use i32 or i64 + Signed, + /// Use u32 or u64 + Unsigned, +} + +impl MacroTypeVariation { + /// Convert a `MacroTypeVariation` to its str representation. + pub fn as_str(&self) -> &str { + match self { + MacroTypeVariation::Signed => "signed", + MacroTypeVariation::Unsigned => "unsigned", + } + } +} + +impl Default for MacroTypeVariation { + fn default() -> MacroTypeVariation { + MacroTypeVariation::Unsigned + } +} + +impl std::str::FromStr for MacroTypeVariation { + type Err = std::io::Error; + + /// Create a `MacroTypeVariation` from a string. + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "signed" => Ok(MacroTypeVariation::Signed), + "unsigned" => Ok(MacroTypeVariation::Unsigned), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + concat!( + "Got an invalid MacroTypeVariation. Accepted values ", + "are 'signed' and 'unsigned'" + ), + )), + } + } +} + /// Enum for how aliases should be translated. #[derive(Copy, Clone, PartialEq, Debug)] pub enum AliasVariation { diff --git a/src/ir/var.rs b/src/ir/var.rs index ef963503..c6f121d7 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -1,5 +1,6 @@ //! Intermediate representation of variables. +use super::super::codegen::MacroTypeVariation; use super::context::{BindgenContext, TypeId}; use super::dot::DotAttributes; use super::function::cursor_mangling; @@ -117,9 +118,12 @@ impl DotAttributes for Var { } // TODO(emilio): we could make this more (or less) granular, I guess. -fn default_macro_constant_type(value: i64) -> IntKind { - if value < 0 { - if value < i32::min_value() as i64 { +fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind { + if value < 0 || + ctx.options().default_macro_constant_type == + MacroTypeVariation::Signed + { + if value < i32::min_value() as i64 || value > i32::max_value() as i64 { IntKind::I64 } else { IntKind::I32 @@ -264,7 +268,7 @@ impl ClangSubItemParser for Var { .parse_callbacks() .and_then(|c| c.int_macro(&name, value)) .unwrap_or_else(|| { - default_macro_constant_type(value) + default_macro_constant_type(&ctx, value) }); (TypeKind::Int(kind), VarType::Int(value)) @@ -72,7 +72,7 @@ doc_mod!(ir, ir_docs); doc_mod!(parse, parse_docs); doc_mod!(regex_set, regex_set_docs); -pub use crate::codegen::{AliasVariation, EnumVariation}; +pub use crate::codegen::{AliasVariation, EnumVariation, MacroTypeVariation}; use crate::features::RustFeatures; pub use crate::features::{ RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS, @@ -267,6 +267,12 @@ impl Builder { ) } + if self.options.default_macro_constant_type != Default::default() { + output_vector.push("--default-macro-constant-type".into()); + output_vector + .push(self.options.default_macro_constant_type.as_str().into()); + } + if self.options.default_alias_style != Default::default() { output_vector.push("--default-alias-style".into()); output_vector @@ -872,6 +878,15 @@ impl Builder { self } + /// Set the default type for macro constants + pub fn default_macro_constant_type( + mut self, + arg: codegen::MacroTypeVariation, + ) -> Builder { + self.options.default_macro_constant_type = arg; + self + } + /// Set the default style of code to generate for typedefs pub fn default_alias_style( mut self, @@ -1513,6 +1528,9 @@ struct BindgenOptions { /// The enum patterns to mark an enum as a set of constants. constified_enums: RegexSet, + /// The default type for C macro constants. + default_macro_constant_type: codegen::MacroTypeVariation, + /// The default style of code to generate for typedefs. default_alias_style: codegen::AliasVariation, @@ -1800,6 +1818,7 @@ impl Default for BindgenOptions { rustified_non_exhaustive_enums: Default::default(), constified_enums: Default::default(), constified_enum_modules: Default::default(), + default_macro_constant_type: Default::default(), default_alias_style: Default::default(), type_alias: Default::default(), new_type_alias: Default::default(), diff --git a/src/options.rs b/src/options.rs index 1ba349a9..a850dbbb 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,6 +1,7 @@ use bindgen::{ - builder, AliasVariation, Builder, CodegenConfig, EnumVariation, RustTarget, - DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, + builder, AliasVariation, Builder, CodegenConfig, EnumVariation, + MacroTypeVariation, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, + RUST_TARGET_STRINGS, }; use clap::{App, Arg}; use std::fs::File; @@ -87,6 +88,13 @@ where .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("default-macro-constant-type") + .long("default-macro-constant-type") + .help("The default signed/unsigned type for C macro constants.") + .value_name("variant") + .default_value("unsigned") + .possible_values(&["signed", "unsigned"]) + .multiple(false), Arg::with_name("default-alias-style") .long("default-alias-style") .help("The default style of code used to generate typedefs.") @@ -522,6 +530,11 @@ where } } + if let Some(variant) = matches.value_of("default-macro-constant-type") { + builder = builder + .default_macro_constant_type(MacroTypeVariation::from_str(variant)?) + } + if let Some(variant) = matches.value_of("default-alias-style") { builder = builder.default_alias_style(AliasVariation::from_str(variant)?); |