|  | use bindgen::callbacks::TypeKind; | 
|  | use bindgen::{ | 
|  | builder, Abi, AliasVariation, Builder, CodegenConfig, EnumVariation, | 
|  | FieldVisibilityKind, Formatter, MacroTypeVariation, NonCopyUnionStyle, | 
|  | RegexSet, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, | 
|  | }; | 
|  | use clap::error::{Error, ErrorKind}; | 
|  | use clap::{CommandFactory, Parser}; | 
|  | use std::fs::File; | 
|  | use std::io; | 
|  | use std::path::{Path, PathBuf}; | 
|  | use std::process::exit; | 
|  |  | 
|  | fn rust_target_help() -> String { | 
|  | format!( | 
|  | "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {}.", | 
|  | RUST_TARGET_STRINGS, | 
|  | RustTarget::default() | 
|  | ) | 
|  | } | 
|  |  | 
|  | fn parse_codegen_config( | 
|  | what_to_generate: &str, | 
|  | ) -> Result<CodegenConfig, Error> { | 
|  | let mut config = CodegenConfig::empty(); | 
|  | for what in what_to_generate.split(',') { | 
|  | match what { | 
|  | "functions" => config.insert(CodegenConfig::FUNCTIONS), | 
|  | "types" => config.insert(CodegenConfig::TYPES), | 
|  | "vars" => config.insert(CodegenConfig::VARS), | 
|  | "methods" => config.insert(CodegenConfig::METHODS), | 
|  | "constructors" => config.insert(CodegenConfig::CONSTRUCTORS), | 
|  | "destructors" => config.insert(CodegenConfig::DESTRUCTORS), | 
|  | otherwise => { | 
|  | return Err(Error::raw( | 
|  | ErrorKind::InvalidValue, | 
|  | format!("Unknown codegen item kind: {}", otherwise), | 
|  | )); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | Ok(config) | 
|  | } | 
|  |  | 
|  | fn parse_rustfmt_config_path(path_str: &str) -> Result<PathBuf, Error> { | 
|  | let path = Path::new(path_str); | 
|  |  | 
|  | if !path.is_absolute() { | 
|  | return Err(Error::raw( | 
|  | ErrorKind::InvalidValue, | 
|  | "--rustfmt-configuration-file needs to be an absolute path!", | 
|  | )); | 
|  | } | 
|  |  | 
|  | if path.to_str().is_none() { | 
|  | return Err(Error::raw( | 
|  | ErrorKind::InvalidUtf8, | 
|  | "--rustfmt-configuration-file contains non-valid UTF8 characters.", | 
|  | )); | 
|  | } | 
|  |  | 
|  | Ok(path.to_path_buf()) | 
|  | } | 
|  |  | 
|  | fn parse_abi_override(abi_override: &str) -> Result<(Abi, String), Error> { | 
|  | let (regex, abi_str) = abi_override | 
|  | .rsplit_once('=') | 
|  | .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?; | 
|  |  | 
|  | let abi = abi_str | 
|  | .parse() | 
|  | .map_err(|err| Error::raw(ErrorKind::InvalidValue, err))?; | 
|  |  | 
|  | Ok((abi, regex.to_owned())) | 
|  | } | 
|  |  | 
|  | fn parse_custom_derive( | 
|  | custom_derive: &str, | 
|  | ) -> Result<(Vec<String>, String), Error> { | 
|  | let (regex, derives) = custom_derive | 
|  | .rsplit_once('=') | 
|  | .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?; | 
|  |  | 
|  | let derives = derives.split(',').map(|s| s.to_owned()).collect(); | 
|  |  | 
|  | Ok((derives, regex.to_owned())) | 
|  | } | 
|  |  | 
|  | #[derive(Parser, Debug)] | 
|  | #[clap( | 
|  | about = "Generates Rust bindings from C/C++ headers.", | 
|  | override_usage = "bindgen <FLAGS> <OPTIONS> <HEADER> -- <CLANG_ARGS>...", | 
|  | trailing_var_arg = true | 
|  | )] | 
|  | struct BindgenCommand { | 
|  | /// C or C++ header file. | 
|  | header: Option<String>, | 
|  | /// Path to write depfile to. | 
|  | #[arg(long)] | 
|  | depfile: Option<String>, | 
|  | /// The default STYLE of code used to generate enums. | 
|  | #[arg(long, value_name = "STYLE")] | 
|  | default_enum_style: Option<EnumVariation>, | 
|  | /// Mark any enum whose name matches REGEX as a set of bitfield flags. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | bitfield_enum: Vec<String>, | 
|  | /// Mark any enum whose name matches REGEX as a newtype. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | newtype_enum: Vec<String>, | 
|  | /// Mark any enum whose name matches REGEX as a global newtype. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | newtype_global_enum: Vec<String>, | 
|  | /// Mark any enum whose name matches REGEX as a Rust enum. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | rustified_enum: Vec<String>, | 
|  | /// Mark any enum whose name matches REGEX as a series of constants. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | constified_enum: Vec<String>, | 
|  | /// Mark any enum whose name matches REGEX as a module of constants. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | constified_enum_module: Vec<String>, | 
|  | /// The default signed/unsigned TYPE for C macro constants. | 
|  | #[arg(long, value_name = "TYPE")] | 
|  | default_macro_constant_type: Option<MacroTypeVariation>, | 
|  | /// The default STYLE of code used to generate typedefs. | 
|  | #[arg(long, value_name = "STYLE")] | 
|  | default_alias_style: Option<AliasVariation>, | 
|  | /// Mark any typedef alias whose name matches REGEX to use normal type aliasing. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | normal_alias: Vec<String>, | 
|  | /// Mark any typedef alias whose name matches REGEX to have a new type generated for it. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | new_type_alias: Vec<String>, | 
|  | /// Mark any typedef alias whose name matches REGEX to have a new type with Deref and DerefMut to the inner type. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | new_type_alias_deref: Vec<String>, | 
|  | /// The default STYLE of code used to generate unions with non-Copy members. Note that ManuallyDrop was first stabilized in Rust 1.20.0. | 
|  | #[arg(long, value_name = "STYLE")] | 
|  | default_non_copy_union_style: Option<NonCopyUnionStyle>, | 
|  | /// Mark any union whose name matches REGEX and who has a non-Copy member to use a bindgen-generated wrapper for fields. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | bindgen_wrapper_union: Vec<String>, | 
|  | /// Mark any union whose name matches REGEX and who has a non-Copy member to use ManuallyDrop (stabilized in Rust 1.20.0) for fields. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | manually_drop_union: Vec<String>, | 
|  | /// Mark TYPE as hidden. | 
|  | #[arg(long, value_name = "TYPE")] | 
|  | blocklist_type: Vec<String>, | 
|  | /// Mark FUNCTION as hidden. | 
|  | #[arg(long, value_name = "FUNCTION")] | 
|  | blocklist_function: Vec<String>, | 
|  | /// Mark ITEM as hidden. | 
|  | #[arg(long, value_name = "ITEM")] | 
|  | blocklist_item: Vec<String>, | 
|  | /// Mark FILE as hidden. | 
|  | #[arg(long, value_name = "FILE")] | 
|  | blocklist_file: Vec<String>, | 
|  | /// Mark VAR as hidden. | 
|  | #[arg(long, value_name = "VAR")] | 
|  | blocklist_var: Vec<String>, | 
|  | /// Avoid generating layout tests for any type. | 
|  | #[arg(long)] | 
|  | no_layout_tests: bool, | 
|  | /// Avoid deriving Copy on any type. | 
|  | #[arg(long)] | 
|  | no_derive_copy: bool, | 
|  | /// Avoid deriving Debug on any type. | 
|  | #[arg(long)] | 
|  | no_derive_debug: bool, | 
|  | /// Avoid deriving Default on any type. | 
|  | #[arg(long, hide = true)] | 
|  | no_derive_default: bool, | 
|  | /// Create a Debug implementation if it cannot be derived automatically. | 
|  | #[arg(long)] | 
|  | impl_debug: bool, | 
|  | /// Create a PartialEq implementation if it cannot be derived automatically. | 
|  | #[arg(long)] | 
|  | impl_partialeq: bool, | 
|  | /// Derive Default on any type. | 
|  | #[arg(long)] | 
|  | with_derive_default: bool, | 
|  | /// Derive Hash on any type. | 
|  | #[arg(long)] | 
|  | with_derive_hash: bool, | 
|  | /// Derive PartialEq on any type. | 
|  | #[arg(long)] | 
|  | with_derive_partialeq: bool, | 
|  | /// Derive PartialOrd on any type. | 
|  | #[arg(long)] | 
|  | with_derive_partialord: bool, | 
|  | /// Derive Eq on any type. | 
|  | #[arg(long)] | 
|  | with_derive_eq: bool, | 
|  | /// Derive Ord on any type. | 
|  | #[arg(long)] | 
|  | with_derive_ord: bool, | 
|  | /// Avoid including doc comments in the output, see: <https://github.com/rust-lang/rust-bindgen/issues/426> | 
|  | #[arg(long)] | 
|  | no_doc_comments: bool, | 
|  | /// Disable allowlisting types recursively. This will cause bindgen to emit Rust code that won't compile! See the `bindgen::Builder::allowlist_recursively` method's documentation for details. | 
|  | #[arg(long)] | 
|  | no_recursive_allowlist: bool, | 
|  | /// Use extern crate instead of use for objc. | 
|  | #[arg(long)] | 
|  | objc_extern_crate: bool, | 
|  | /// Generate block signatures instead of void pointers. | 
|  | #[arg(long)] | 
|  | generate_block: bool, | 
|  | /// Generate string constants as `&CStr` instead of `&[u8]`. | 
|  | #[arg(long)] | 
|  | generate_cstr: bool, | 
|  | /// Use extern crate instead of use for block. | 
|  | #[arg(long)] | 
|  | block_extern_crate: bool, | 
|  | /// Do not trust the libclang-provided mangling | 
|  | #[arg(long)] | 
|  | distrust_clang_mangling: bool, | 
|  | /// Output bindings for builtin definitions, e.g. __builtin_va_list. | 
|  | #[arg(long)] | 
|  | builtins: bool, | 
|  | /// Use the given PREFIX before raw types instead of ::std::os::raw. | 
|  | #[arg(long, value_name = "PREFIX")] | 
|  | ctypes_prefix: Option<String>, | 
|  | /// Use the given PREFIX for anonymous fields. | 
|  | #[arg(long, default_value = DEFAULT_ANON_FIELDS_PREFIX, value_name = "PREFIX")] | 
|  | anon_fields_prefix: String, | 
|  | /// Time the different bindgen phases and print to stderr | 
|  | #[arg(long)] | 
|  | time_phases: bool, | 
|  | /// Output the Clang AST for debugging purposes. | 
|  | #[arg(long)] | 
|  | emit_clang_ast: bool, | 
|  | /// Output our internal IR for debugging purposes. | 
|  | #[arg(long)] | 
|  | emit_ir: bool, | 
|  | /// Dump a graphviz dot file to PATH. | 
|  | #[arg(long, value_name = "PATH")] | 
|  | emit_ir_graphviz: Option<String>, | 
|  | /// Enable support for C++ namespaces. | 
|  | #[arg(long)] | 
|  | enable_cxx_namespaces: bool, | 
|  | /// Disable namespacing via mangling, causing bindgen to generate names like `Baz` instead of `foo_bar_Baz` for an input name `foo::bar::Baz`. | 
|  | #[arg(long)] | 
|  | disable_name_namespacing: bool, | 
|  | /// Disable nested struct naming, causing bindgen to generate names like `bar` instead of `foo_bar` for a nested definition `struct foo { struct bar { } b; };`. | 
|  | #[arg(long)] | 
|  | disable_nested_struct_naming: bool, | 
|  | /// Disable support for native Rust unions. | 
|  | #[arg(long)] | 
|  | disable_untagged_union: bool, | 
|  | /// Suppress insertion of bindgen's version identifier into generated bindings. | 
|  | #[arg(long)] | 
|  | disable_header_comment: bool, | 
|  | /// Do not generate bindings for functions or methods. This is useful when you only care about struct layouts. | 
|  | #[arg(long)] | 
|  | ignore_functions: bool, | 
|  | /// Generate only given items, split by commas. Valid values are `functions`,`types`, `vars`, `methods`, `constructors` and `destructors`. | 
|  | #[arg(long, value_parser = parse_codegen_config)] | 
|  | generate: Option<CodegenConfig>, | 
|  | /// Do not generate bindings for methods. | 
|  | #[arg(long)] | 
|  | ignore_methods: bool, | 
|  | /// Do not automatically convert floats to f32/f64. | 
|  | #[arg(long)] | 
|  | no_convert_floats: bool, | 
|  | /// Do not prepend the enum name to constant or newtype variants. | 
|  | #[arg(long)] | 
|  | no_prepend_enum_name: bool, | 
|  | /// Do not try to detect default include paths | 
|  | #[arg(long)] | 
|  | no_include_path_detection: bool, | 
|  | /// Try to fit macro constants into types smaller than u32/i32 | 
|  | #[arg(long)] | 
|  | fit_macro_constant_types: bool, | 
|  | /// Mark TYPE as opaque. | 
|  | #[arg(long, value_name = "TYPE")] | 
|  | opaque_type: Vec<String>, | 
|  | ///  Write Rust bindings to OUTPUT. | 
|  | #[arg(long, short, value_name = "OUTPUT")] | 
|  | output: Option<String>, | 
|  | /// Add a raw line of Rust code at the beginning of output. | 
|  | #[arg(long)] | 
|  | raw_line: Vec<String>, | 
|  | /// Add a RAW_LINE of Rust code to a given module with name MODULE_NAME. | 
|  | #[arg(long, number_of_values = 2, value_names = ["MODULE_NAME", "RAW_LINE"])] | 
|  | module_raw_line: Vec<String>, | 
|  | #[arg(long, help = rust_target_help())] | 
|  | rust_target: Option<RustTarget>, | 
|  | /// Use types from Rust core instead of std. | 
|  | #[arg(long)] | 
|  | use_core: bool, | 
|  | /// Conservatively generate inline namespaces to avoid name conflicts. | 
|  | #[arg(long)] | 
|  | conservative_inline_namespaces: bool, | 
|  | /// Allowlist all the free-standing functions matching REGEX. Other non-allowlisted functions will not be generated. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | allowlist_function: Vec<String>, | 
|  | /// Generate inline functions. | 
|  | #[arg(long)] | 
|  | generate_inline_functions: bool, | 
|  | /// Only generate types matching REGEX. Other non-allowlisted types will not be generated. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | allowlist_type: Vec<String>, | 
|  | /// Allowlist all the free-standing variables matching REGEX. Other non-allowlisted variables will not be generated. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | allowlist_var: Vec<String>, | 
|  | /// Allowlist all contents of PATH. | 
|  | #[arg(long, value_name = "PATH")] | 
|  | allowlist_file: Vec<String>, | 
|  | /// Allowlist all items matching REGEX. Other non-allowlisted items will not be generated. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | allowlist_item: Vec<String>, | 
|  | /// Print verbose error messages. | 
|  | #[arg(long)] | 
|  | verbose: bool, | 
|  | /// Preprocess and dump the input header files to disk. Useful when debugging bindgen, using C-Reduce, or when filing issues. The resulting file will be named something like `__bindgen.i` or `__bindgen.ii`. | 
|  | #[arg(long)] | 
|  | dump_preprocessed_input: bool, | 
|  | /// Do not record matching items in the regex sets. This disables reporting of unused items. | 
|  | #[arg(long)] | 
|  | no_record_matches: bool, | 
|  | /// Do not bind size_t as usize (useful on platforms where those types are incompatible). | 
|  | #[arg(long = "no-size_t-is-usize")] | 
|  | no_size_t_is_usize: bool, | 
|  | /// Do not format the generated bindings with rustfmt. This option is deprecated, please use | 
|  | /// `--formatter=none` instead. | 
|  | #[arg(long)] | 
|  | no_rustfmt_bindings: bool, | 
|  | /// Which FORMATTER should be used for the bindings | 
|  | #[arg( | 
|  | long, | 
|  | value_name = "FORMATTER", | 
|  | conflicts_with = "no_rustfmt_bindings" | 
|  | )] | 
|  | formatter: Option<Formatter>, | 
|  | /// The absolute PATH to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter sets `formatter` to `rustfmt`. | 
|  | #[arg(long, value_name = "PATH", conflicts_with = "no_rustfmt_bindings", value_parser=parse_rustfmt_config_path)] | 
|  | rustfmt_configuration_file: Option<PathBuf>, | 
|  | /// Avoid deriving PartialEq for types matching REGEX. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | no_partialeq: Vec<String>, | 
|  | /// Avoid deriving Copy and Clone for types matching REGEX. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | no_copy: Vec<String>, | 
|  | /// Avoid deriving Debug for types matching REGEX. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | no_debug: Vec<String>, | 
|  | /// Avoid deriving/implementing Default for types matching REGEX. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | no_default: Vec<String>, | 
|  | /// Avoid deriving Hash for types matching REGEX. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | no_hash: Vec<String>, | 
|  | /// Add `#[must_use]` annotation to types matching REGEX. | 
|  | #[arg(long, value_name = "REGEX")] | 
|  | must_use_type: Vec<String>, | 
|  | /// Enables detecting unexposed attributes in functions (slow). Used to generate `#[must_use]` annotations. | 
|  | #[arg(long)] | 
|  | enable_function_attribute_detection: bool, | 
|  | /// Use `*const [T; size]` instead of `*const T` for C arrays | 
|  | #[arg(long)] | 
|  | use_array_pointers_in_arguments: bool, | 
|  | /// The NAME to be used in a #[link(wasm_import_module = ...)] statement | 
|  | #[arg(long, value_name = "NAME")] | 
|  | wasm_import_module_name: Option<String>, | 
|  | /// Use dynamic loading mode with the given library NAME. | 
|  | #[arg(long, value_name = "NAME")] | 
|  | dynamic_loading: Option<String>, | 
|  | /// Require successful linkage to all functions in the library. | 
|  | #[arg(long)] | 
|  | dynamic_link_require_all: bool, | 
|  | /// Prefix the name of exported symbols. | 
|  | #[arg(long)] | 
|  | prefix_link_name: Option<String>, | 
|  | /// Makes generated bindings `pub` only for items if the items are publically accessible in C++. | 
|  | #[arg(long)] | 
|  | respect_cxx_access_specs: bool, | 
|  | /// Always translate enum integer types to native Rust integer types. | 
|  | #[arg(long)] | 
|  | translate_enum_integer_types: bool, | 
|  | /// Generate types with C style naming. | 
|  | #[arg(long)] | 
|  | c_naming: bool, | 
|  | /// Always output explicit padding fields. | 
|  | #[arg(long)] | 
|  | explicit_padding: bool, | 
|  | /// Enables generation of vtable functions. | 
|  | #[arg(long)] | 
|  | vtable_generation: bool, | 
|  | /// Enables sorting of code generation in a predefined manner. | 
|  | #[arg(long)] | 
|  | sort_semantically: bool, | 
|  | /// Deduplicates extern blocks. | 
|  | #[arg(long)] | 
|  | merge_extern_blocks: bool, | 
|  | /// Overrides the ABI of functions matching REGEX. The OVERRIDE value must be of the shape REGEX=ABI where ABI can be one of C, stdcall, efiapi, fastcall, thiscall, aapcs, win64 or C-unwind<.> | 
|  | #[arg(long, value_name = "OVERRIDE", value_parser = parse_abi_override)] | 
|  | override_abi: Vec<(Abi, String)>, | 
|  | /// Wrap unsafe operations in unsafe blocks. | 
|  | #[arg(long)] | 
|  | wrap_unsafe_ops: bool, | 
|  | /// Derive custom traits on any kind of type. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. | 
|  | #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] | 
|  | with_derive_custom: Vec<(Vec<String>, String)>, | 
|  | /// Derive custom traits on a `struct`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. | 
|  | #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] | 
|  | with_derive_custom_struct: Vec<(Vec<String>, String)>, | 
|  | /// Derive custom traits on an `enum. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. | 
|  | #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] | 
|  | with_derive_custom_enum: Vec<(Vec<String>, String)>, | 
|  | /// Derive custom traits on a `union`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. | 
|  | #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] | 
|  | with_derive_custom_union: Vec<(Vec<String>, String)>, | 
|  | /// Generate wrappers for `static` and `static inline` functions. | 
|  | #[arg(long, requires = "experimental")] | 
|  | wrap_static_fns: bool, | 
|  | /// Sets the PATH for the source file that must be created due to the presence of `static` and | 
|  | /// `static inline` functions. | 
|  | #[arg(long, requires = "experimental", value_name = "PATH")] | 
|  | wrap_static_fns_path: Option<PathBuf>, | 
|  | /// Sets the SUFFIX added to the extern wrapper functions generated for `static` and `static | 
|  | /// inline` functions. | 
|  | #[arg(long, requires = "experimental", value_name = "SUFFIX")] | 
|  | wrap_static_fns_suffix: Option<String>, | 
|  | /// Set the default VISIBILITY of fields, including bitfields and accessor methods for | 
|  | /// bitfields. This flag is ignored if the `--respect-cxx-access-specs` flag is used. | 
|  | #[arg(long, value_name = "VISIBILITY")] | 
|  | default_visibility: Option<FieldVisibilityKind>, | 
|  | /// Whether to emit diagnostics or not. | 
|  | #[arg(long, requires = "experimental")] | 
|  | emit_diagnostics: bool, | 
|  | /// Generates completions for the specified SHELL, sends them to `stdout` and exits. | 
|  | #[arg(long, value_name = "SHELL")] | 
|  | generate_shell_completions: Option<clap_complete::Shell>, | 
|  | /// Enables experimental features. | 
|  | #[arg(long)] | 
|  | experimental: bool, | 
|  | /// Prints the version, and exits | 
|  | #[arg(short = 'V', long)] | 
|  | version: bool, | 
|  | /// Arguments to be passed straight through to clang. | 
|  | clang_args: Vec<String>, | 
|  | } | 
|  |  | 
|  | /// Construct a new [`Builder`](./struct.Builder.html) from command line flags. | 
|  | pub fn builder_from_flags<I>( | 
|  | args: I, | 
|  | ) -> Result<(Builder, Box<dyn io::Write>, bool), io::Error> | 
|  | where | 
|  | I: Iterator<Item = String>, | 
|  | { | 
|  | let command = BindgenCommand::parse_from(args); | 
|  |  | 
|  | let BindgenCommand { | 
|  | header, | 
|  | depfile, | 
|  | default_enum_style, | 
|  | bitfield_enum, | 
|  | newtype_enum, | 
|  | newtype_global_enum, | 
|  | rustified_enum, | 
|  | constified_enum, | 
|  | constified_enum_module, | 
|  | default_macro_constant_type, | 
|  | default_alias_style, | 
|  | normal_alias, | 
|  | new_type_alias, | 
|  | new_type_alias_deref, | 
|  | default_non_copy_union_style, | 
|  | bindgen_wrapper_union, | 
|  | manually_drop_union, | 
|  | blocklist_type, | 
|  | blocklist_function, | 
|  | blocklist_item, | 
|  | blocklist_file, | 
|  | blocklist_var, | 
|  | no_layout_tests, | 
|  | no_derive_copy, | 
|  | no_derive_debug, | 
|  | no_derive_default, | 
|  | impl_debug, | 
|  | impl_partialeq, | 
|  | with_derive_default, | 
|  | with_derive_hash, | 
|  | with_derive_partialeq, | 
|  | with_derive_partialord, | 
|  | with_derive_eq, | 
|  | with_derive_ord, | 
|  | no_doc_comments, | 
|  | no_recursive_allowlist, | 
|  | objc_extern_crate, | 
|  | generate_block, | 
|  | generate_cstr, | 
|  | block_extern_crate, | 
|  | distrust_clang_mangling, | 
|  | builtins, | 
|  | ctypes_prefix, | 
|  | anon_fields_prefix, | 
|  | time_phases, | 
|  | emit_clang_ast, | 
|  | emit_ir, | 
|  | emit_ir_graphviz, | 
|  | enable_cxx_namespaces, | 
|  | disable_name_namespacing, | 
|  | disable_nested_struct_naming, | 
|  | disable_untagged_union, | 
|  | disable_header_comment, | 
|  | ignore_functions, | 
|  | generate, | 
|  | ignore_methods, | 
|  | no_convert_floats, | 
|  | no_prepend_enum_name, | 
|  | no_include_path_detection, | 
|  | fit_macro_constant_types, | 
|  | opaque_type, | 
|  | output, | 
|  | raw_line, | 
|  | module_raw_line, | 
|  | rust_target, | 
|  | use_core, | 
|  | conservative_inline_namespaces, | 
|  | allowlist_function, | 
|  | generate_inline_functions, | 
|  | allowlist_type, | 
|  | allowlist_var, | 
|  | allowlist_file, | 
|  | allowlist_item, | 
|  | verbose, | 
|  | dump_preprocessed_input, | 
|  | no_record_matches, | 
|  | no_size_t_is_usize, | 
|  | no_rustfmt_bindings, | 
|  | formatter, | 
|  | rustfmt_configuration_file, | 
|  | no_partialeq, | 
|  | no_copy, | 
|  | no_debug, | 
|  | no_default, | 
|  | no_hash, | 
|  | must_use_type, | 
|  | enable_function_attribute_detection, | 
|  | use_array_pointers_in_arguments, | 
|  | wasm_import_module_name, | 
|  | dynamic_loading, | 
|  | dynamic_link_require_all, | 
|  | prefix_link_name, | 
|  | respect_cxx_access_specs, | 
|  | translate_enum_integer_types, | 
|  | c_naming, | 
|  | explicit_padding, | 
|  | vtable_generation, | 
|  | sort_semantically, | 
|  | merge_extern_blocks, | 
|  | override_abi, | 
|  | wrap_unsafe_ops, | 
|  | with_derive_custom, | 
|  | with_derive_custom_struct, | 
|  | with_derive_custom_enum, | 
|  | with_derive_custom_union, | 
|  | wrap_static_fns, | 
|  | wrap_static_fns_path, | 
|  | wrap_static_fns_suffix, | 
|  | default_visibility, | 
|  | emit_diagnostics, | 
|  | generate_shell_completions, | 
|  | experimental: _, | 
|  | version, | 
|  | clang_args, | 
|  | } = command; | 
|  |  | 
|  | if let Some(shell) = generate_shell_completions { | 
|  | clap_complete::generate( | 
|  | shell, | 
|  | &mut BindgenCommand::command(), | 
|  | "bindgen", | 
|  | &mut std::io::stdout(), | 
|  | ); | 
|  |  | 
|  | exit(0); | 
|  | } | 
|  |  | 
|  | if version { | 
|  | println!( | 
|  | "bindgen {}", | 
|  | option_env!("CARGO_PKG_VERSION").unwrap_or("unknown") | 
|  | ); | 
|  | if verbose { | 
|  | println!("Clang: {}", bindgen::clang_version().full); | 
|  | } | 
|  | std::process::exit(0); | 
|  | } | 
|  |  | 
|  | let mut builder = builder(); | 
|  |  | 
|  | if let Some(header) = header { | 
|  | builder = builder.header(header); | 
|  | } else { | 
|  | return Err(io::Error::new(io::ErrorKind::Other, "Header not found")); | 
|  | } | 
|  |  | 
|  | if let Some(rust_target) = rust_target { | 
|  | builder = builder.rust_target(rust_target); | 
|  | } | 
|  |  | 
|  | if let Some(variant) = default_enum_style { | 
|  | builder = builder.default_enum_style(variant); | 
|  | } | 
|  |  | 
|  | for regex in bitfield_enum { | 
|  | builder = builder.bitfield_enum(regex); | 
|  | } | 
|  |  | 
|  | for regex in newtype_enum { | 
|  | builder = builder.newtype_enum(regex); | 
|  | } | 
|  |  | 
|  | for regex in newtype_global_enum { | 
|  | builder = builder.newtype_global_enum(regex); | 
|  | } | 
|  |  | 
|  | for regex in rustified_enum { | 
|  | builder = builder.rustified_enum(regex); | 
|  | } | 
|  |  | 
|  | for regex in constified_enum { | 
|  | builder = builder.constified_enum(regex); | 
|  | } | 
|  |  | 
|  | for regex in constified_enum_module { | 
|  | builder = builder.constified_enum_module(regex); | 
|  | } | 
|  |  | 
|  | if let Some(default_macro_constant_type) = default_macro_constant_type { | 
|  | builder = | 
|  | builder.default_macro_constant_type(default_macro_constant_type) | 
|  | } | 
|  |  | 
|  | if let Some(variant) = default_alias_style { | 
|  | builder = builder.default_alias_style(variant); | 
|  | } | 
|  |  | 
|  | for regex in normal_alias { | 
|  | builder = builder.type_alias(regex); | 
|  | } | 
|  |  | 
|  | for regex in new_type_alias { | 
|  | builder = builder.new_type_alias(regex); | 
|  | } | 
|  |  | 
|  | for regex in new_type_alias_deref { | 
|  | builder = builder.new_type_alias_deref(regex); | 
|  | } | 
|  |  | 
|  | if let Some(variant) = default_non_copy_union_style { | 
|  | builder = builder.default_non_copy_union_style(variant); | 
|  | } | 
|  |  | 
|  | for regex in bindgen_wrapper_union { | 
|  | builder = builder.bindgen_wrapper_union(regex); | 
|  | } | 
|  |  | 
|  | for regex in manually_drop_union { | 
|  | builder = builder.manually_drop_union(regex); | 
|  | } | 
|  |  | 
|  | for ty in blocklist_type { | 
|  | builder = builder.blocklist_type(ty); | 
|  | } | 
|  |  | 
|  | for fun in blocklist_function { | 
|  | builder = builder.blocklist_function(fun); | 
|  | } | 
|  |  | 
|  | for id in blocklist_item { | 
|  | builder = builder.blocklist_item(id); | 
|  | } | 
|  |  | 
|  | for file in blocklist_file { | 
|  | builder = builder.blocklist_file(file); | 
|  | } | 
|  |  | 
|  | for var in blocklist_var { | 
|  | builder = builder.blocklist_var(var); | 
|  | } | 
|  |  | 
|  | if builtins { | 
|  | builder = builder.emit_builtins(); | 
|  | } | 
|  |  | 
|  | if no_layout_tests { | 
|  | builder = builder.layout_tests(false); | 
|  | } | 
|  |  | 
|  | if no_derive_copy { | 
|  | builder = builder.derive_copy(false); | 
|  | } | 
|  |  | 
|  | if no_derive_debug { | 
|  | builder = builder.derive_debug(false); | 
|  | } | 
|  |  | 
|  | if impl_debug { | 
|  | builder = builder.impl_debug(true); | 
|  | } | 
|  |  | 
|  | if impl_partialeq { | 
|  | builder = builder.impl_partialeq(true); | 
|  | } | 
|  |  | 
|  | if with_derive_default { | 
|  | builder = builder.derive_default(true); | 
|  | } | 
|  |  | 
|  | if with_derive_hash { | 
|  | builder = builder.derive_hash(true); | 
|  | } | 
|  |  | 
|  | if with_derive_partialeq { | 
|  | builder = builder.derive_partialeq(true); | 
|  | } | 
|  |  | 
|  | if with_derive_partialord { | 
|  | builder = builder.derive_partialord(true); | 
|  | } | 
|  |  | 
|  | if with_derive_eq { | 
|  | builder = builder.derive_eq(true); | 
|  | } | 
|  |  | 
|  | if with_derive_ord { | 
|  | builder = builder.derive_ord(true); | 
|  | } | 
|  |  | 
|  | if no_derive_default { | 
|  | builder = builder.derive_default(false); | 
|  | } | 
|  |  | 
|  | if no_prepend_enum_name { | 
|  | builder = builder.prepend_enum_name(false); | 
|  | } | 
|  |  | 
|  | if no_include_path_detection { | 
|  | builder = builder.detect_include_paths(false); | 
|  | } | 
|  |  | 
|  | if fit_macro_constant_types { | 
|  | builder = builder.fit_macro_constants(true); | 
|  | } | 
|  |  | 
|  | if time_phases { | 
|  | builder = builder.time_phases(true); | 
|  | } | 
|  |  | 
|  | if use_array_pointers_in_arguments { | 
|  | builder = builder.array_pointers_in_arguments(true); | 
|  | } | 
|  |  | 
|  | if let Some(wasm_import_name) = wasm_import_module_name { | 
|  | builder = builder.wasm_import_module_name(wasm_import_name); | 
|  | } | 
|  |  | 
|  | if let Some(prefix) = ctypes_prefix { | 
|  | builder = builder.ctypes_prefix(prefix); | 
|  | } | 
|  |  | 
|  | builder = builder.anon_fields_prefix(anon_fields_prefix); | 
|  |  | 
|  | if let Some(config) = generate { | 
|  | builder = builder.with_codegen_config(config); | 
|  | } | 
|  |  | 
|  | if emit_clang_ast { | 
|  | builder = builder.emit_clang_ast(); | 
|  | } | 
|  |  | 
|  | if emit_ir { | 
|  | builder = builder.emit_ir(); | 
|  | } | 
|  |  | 
|  | if let Some(path) = emit_ir_graphviz { | 
|  | builder = builder.emit_ir_graphviz(path); | 
|  | } | 
|  |  | 
|  | if enable_cxx_namespaces { | 
|  | builder = builder.enable_cxx_namespaces(); | 
|  | } | 
|  |  | 
|  | if enable_function_attribute_detection { | 
|  | builder = builder.enable_function_attribute_detection(); | 
|  | } | 
|  |  | 
|  | if disable_name_namespacing { | 
|  | builder = builder.disable_name_namespacing(); | 
|  | } | 
|  |  | 
|  | if disable_nested_struct_naming { | 
|  | builder = builder.disable_nested_struct_naming(); | 
|  | } | 
|  |  | 
|  | if disable_untagged_union { | 
|  | builder = builder.disable_untagged_union(); | 
|  | } | 
|  |  | 
|  | if disable_header_comment { | 
|  | builder = builder.disable_header_comment(); | 
|  | } | 
|  |  | 
|  | if ignore_functions { | 
|  | builder = builder.ignore_functions(); | 
|  | } | 
|  |  | 
|  | if ignore_methods { | 
|  | builder = builder.ignore_methods(); | 
|  | } | 
|  |  | 
|  | if no_convert_floats { | 
|  | builder = builder.no_convert_floats(); | 
|  | } | 
|  |  | 
|  | if no_doc_comments { | 
|  | builder = builder.generate_comments(false); | 
|  | } | 
|  |  | 
|  | if no_recursive_allowlist { | 
|  | builder = builder.allowlist_recursively(false); | 
|  | } | 
|  |  | 
|  | if objc_extern_crate { | 
|  | builder = builder.objc_extern_crate(true); | 
|  | } | 
|  |  | 
|  | if generate_block { | 
|  | builder = builder.generate_block(true); | 
|  | } | 
|  |  | 
|  | if generate_cstr { | 
|  | builder = builder.generate_cstr(true); | 
|  | } | 
|  |  | 
|  | if block_extern_crate { | 
|  | builder = builder.block_extern_crate(true); | 
|  | } | 
|  |  | 
|  | for ty in opaque_type { | 
|  | builder = builder.opaque_type(ty); | 
|  | } | 
|  |  | 
|  | for line in raw_line { | 
|  | builder = builder.raw_line(line); | 
|  | } | 
|  |  | 
|  | let mut values = module_raw_line.into_iter(); | 
|  | while let Some(module) = values.next() { | 
|  | let line = values.next().unwrap(); | 
|  | builder = builder.module_raw_line(module, line); | 
|  | } | 
|  |  | 
|  | if use_core { | 
|  | builder = builder.use_core(); | 
|  | } | 
|  |  | 
|  | if distrust_clang_mangling { | 
|  | builder = builder.trust_clang_mangling(false); | 
|  | } | 
|  |  | 
|  | if conservative_inline_namespaces { | 
|  | builder = builder.conservative_inline_namespaces(); | 
|  | } | 
|  |  | 
|  | if generate_inline_functions { | 
|  | builder = builder.generate_inline_functions(true); | 
|  | } | 
|  |  | 
|  | for regex in allowlist_function { | 
|  | builder = builder.allowlist_function(regex); | 
|  | } | 
|  |  | 
|  | for regex in allowlist_type { | 
|  | builder = builder.allowlist_type(regex); | 
|  | } | 
|  |  | 
|  | for regex in allowlist_var { | 
|  | builder = builder.allowlist_var(regex); | 
|  | } | 
|  |  | 
|  | for file in allowlist_file { | 
|  | builder = builder.allowlist_file(file); | 
|  | } | 
|  |  | 
|  | for item in allowlist_item { | 
|  | builder = builder.allowlist_item(item); | 
|  | } | 
|  |  | 
|  | for arg in clang_args { | 
|  | builder = builder.clang_arg(arg); | 
|  | } | 
|  |  | 
|  | let output = if let Some(path) = &output { | 
|  | let file = File::create(path)?; | 
|  | if let Some(depfile) = depfile { | 
|  | builder = builder.depfile(path, depfile); | 
|  | } | 
|  | Box::new(io::BufWriter::new(file)) as Box<dyn io::Write> | 
|  | } else { | 
|  | if let Some(depfile) = depfile { | 
|  | builder = builder.depfile("-", depfile); | 
|  | } | 
|  | Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write> | 
|  | }; | 
|  |  | 
|  | if dump_preprocessed_input { | 
|  | builder.dump_preprocessed_input()?; | 
|  | } | 
|  |  | 
|  | if no_record_matches { | 
|  | builder = builder.record_matches(false); | 
|  | } | 
|  |  | 
|  | if no_size_t_is_usize { | 
|  | builder = builder.size_t_is_usize(false); | 
|  | } | 
|  |  | 
|  | if no_rustfmt_bindings { | 
|  | builder = builder.formatter(Formatter::None); | 
|  | } | 
|  |  | 
|  | if let Some(formatter) = formatter { | 
|  | builder = builder.formatter(formatter); | 
|  | } | 
|  |  | 
|  | if let Some(path) = rustfmt_configuration_file { | 
|  | builder = builder.rustfmt_configuration_file(Some(path)); | 
|  | } | 
|  |  | 
|  | for regex in no_partialeq { | 
|  | builder = builder.no_partialeq(regex); | 
|  | } | 
|  |  | 
|  | for regex in no_copy { | 
|  | builder = builder.no_copy(regex); | 
|  | } | 
|  |  | 
|  | for regex in no_debug { | 
|  | builder = builder.no_debug(regex); | 
|  | } | 
|  |  | 
|  | for regex in no_default { | 
|  | builder = builder.no_default(regex); | 
|  | } | 
|  |  | 
|  | for regex in no_hash { | 
|  | builder = builder.no_hash(regex); | 
|  | } | 
|  |  | 
|  | for regex in must_use_type { | 
|  | builder = builder.must_use_type(regex); | 
|  | } | 
|  |  | 
|  | if let Some(dynamic_library_name) = dynamic_loading { | 
|  | builder = builder.dynamic_library_name(dynamic_library_name); | 
|  | } | 
|  |  | 
|  | if dynamic_link_require_all { | 
|  | builder = builder.dynamic_link_require_all(true); | 
|  | } | 
|  |  | 
|  | if let Some(prefix_link_name) = prefix_link_name { | 
|  | #[derive(Debug)] | 
|  | struct PrefixLinkNameCallback { | 
|  | prefix: String, | 
|  | } | 
|  |  | 
|  | impl bindgen::callbacks::ParseCallbacks for PrefixLinkNameCallback { | 
|  | fn generated_link_name_override( | 
|  | &self, | 
|  | item_info: bindgen::callbacks::ItemInfo<'_>, | 
|  | ) -> Option<String> { | 
|  | let mut prefix = self.prefix.clone(); | 
|  | prefix.push_str(item_info.name); | 
|  | Some(prefix) | 
|  | } | 
|  | } | 
|  |  | 
|  | builder = builder.parse_callbacks(Box::new(PrefixLinkNameCallback { | 
|  | prefix: prefix_link_name, | 
|  | })) | 
|  | } | 
|  |  | 
|  | if respect_cxx_access_specs { | 
|  | builder = builder.respect_cxx_access_specs(true); | 
|  | } | 
|  |  | 
|  | if translate_enum_integer_types { | 
|  | builder = builder.translate_enum_integer_types(true); | 
|  | } | 
|  |  | 
|  | if c_naming { | 
|  | builder = builder.c_naming(true); | 
|  | } | 
|  |  | 
|  | if explicit_padding { | 
|  | builder = builder.explicit_padding(true); | 
|  | } | 
|  |  | 
|  | if vtable_generation { | 
|  | builder = builder.vtable_generation(true); | 
|  | } | 
|  |  | 
|  | if sort_semantically { | 
|  | builder = builder.sort_semantically(true); | 
|  | } | 
|  |  | 
|  | if merge_extern_blocks { | 
|  | builder = builder.merge_extern_blocks(true); | 
|  | } | 
|  |  | 
|  | for (abi, regex) in override_abi { | 
|  | builder = builder.override_abi(abi, regex); | 
|  | } | 
|  |  | 
|  | if wrap_unsafe_ops { | 
|  | builder = builder.wrap_unsafe_ops(true); | 
|  | } | 
|  |  | 
|  | #[derive(Debug)] | 
|  | struct CustomDeriveCallback { | 
|  | derives: Vec<String>, | 
|  | kind: Option<TypeKind>, | 
|  | regex_set: bindgen::RegexSet, | 
|  | } | 
|  |  | 
|  | impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback { | 
|  | fn cli_args(&self) -> Vec<String> { | 
|  | let mut args = vec![]; | 
|  |  | 
|  | let flag = match &self.kind { | 
|  | None => "--with-derive-custom", | 
|  | Some(TypeKind::Struct) => "--with-derive-custom-struct", | 
|  | Some(TypeKind::Enum) => "--with-derive-custom-enum", | 
|  | Some(TypeKind::Union) => "--with-derive-custom-union", | 
|  | }; | 
|  |  | 
|  | let derives = self.derives.join(","); | 
|  |  | 
|  | for item in self.regex_set.get_items() { | 
|  | args.extend_from_slice(&[ | 
|  | flag.to_owned(), | 
|  | format!("{}={}", item, derives), | 
|  | ]); | 
|  | } | 
|  |  | 
|  | args | 
|  | } | 
|  |  | 
|  | fn add_derives( | 
|  | &self, | 
|  | info: &bindgen::callbacks::DeriveInfo<'_>, | 
|  | ) -> Vec<String> { | 
|  | if self.kind.map(|kind| kind == info.kind).unwrap_or(true) && | 
|  | self.regex_set.matches(info.name) | 
|  | { | 
|  | return self.derives.clone(); | 
|  | } | 
|  | vec![] | 
|  | } | 
|  | } | 
|  |  | 
|  | for (custom_derives, kind, name) in [ | 
|  | (with_derive_custom, None, "--with-derive-custom"), | 
|  | ( | 
|  | with_derive_custom_struct, | 
|  | Some(TypeKind::Struct), | 
|  | "--with-derive-custom-struct", | 
|  | ), | 
|  | ( | 
|  | with_derive_custom_enum, | 
|  | Some(TypeKind::Enum), | 
|  | "--with-derive-custom-enum", | 
|  | ), | 
|  | ( | 
|  | with_derive_custom_union, | 
|  | Some(TypeKind::Union), | 
|  | "--with-derive-custom-union", | 
|  | ), | 
|  | ] { | 
|  | let name = emit_diagnostics.then_some(name); | 
|  | for (derives, regex) in custom_derives { | 
|  | let mut regex_set = RegexSet::new(); | 
|  | regex_set.insert(regex); | 
|  | regex_set.build_with_diagnostics(false, name); | 
|  |  | 
|  | builder = builder.parse_callbacks(Box::new(CustomDeriveCallback { | 
|  | derives, | 
|  | kind, | 
|  | regex_set, | 
|  | })); | 
|  | } | 
|  | } | 
|  |  | 
|  | if wrap_static_fns { | 
|  | builder = builder.wrap_static_fns(true); | 
|  | } | 
|  |  | 
|  | if let Some(path) = wrap_static_fns_path { | 
|  | builder = builder.wrap_static_fns_path(path); | 
|  | } | 
|  |  | 
|  | if let Some(suffix) = wrap_static_fns_suffix { | 
|  | builder = builder.wrap_static_fns_suffix(suffix); | 
|  | } | 
|  |  | 
|  | if let Some(visibility) = default_visibility { | 
|  | builder = builder.default_visibility(visibility); | 
|  | } | 
|  |  | 
|  | if emit_diagnostics { | 
|  | builder = builder.emit_diagnostics(); | 
|  | } | 
|  |  | 
|  | Ok((builder, output, verbose)) | 
|  | } |