112a9d9c8Sopenharmony_ciuse bindgen::callbacks::TypeKind; 212a9d9c8Sopenharmony_ciuse bindgen::{ 312a9d9c8Sopenharmony_ci builder, AliasVariation, Builder, CodegenConfig, EnumVariation, 412a9d9c8Sopenharmony_ci MacroTypeVariation, NonCopyUnionStyle, RegexSet, RustTarget, 512a9d9c8Sopenharmony_ci DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, 612a9d9c8Sopenharmony_ci}; 712a9d9c8Sopenharmony_ciuse clap::Parser; 812a9d9c8Sopenharmony_ciuse std::fs::File; 912a9d9c8Sopenharmony_ciuse std::io::{self, Error, ErrorKind}; 1012a9d9c8Sopenharmony_ciuse std::path::PathBuf; 1112a9d9c8Sopenharmony_ci 1212a9d9c8Sopenharmony_cifn rust_target_help() -> String { 1312a9d9c8Sopenharmony_ci format!( 1412a9d9c8Sopenharmony_ci "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {:?}.", 1512a9d9c8Sopenharmony_ci RUST_TARGET_STRINGS, 1612a9d9c8Sopenharmony_ci String::from(RustTarget::default()) 1712a9d9c8Sopenharmony_ci ) 1812a9d9c8Sopenharmony_ci} 1912a9d9c8Sopenharmony_ci 2012a9d9c8Sopenharmony_cifn parse_codegen_config(what_to_generate: &str) -> io::Result<CodegenConfig> { 2112a9d9c8Sopenharmony_ci let mut config = CodegenConfig::empty(); 2212a9d9c8Sopenharmony_ci for what in what_to_generate.split(',') { 2312a9d9c8Sopenharmony_ci match what { 2412a9d9c8Sopenharmony_ci "functions" => config.insert(CodegenConfig::FUNCTIONS), 2512a9d9c8Sopenharmony_ci "types" => config.insert(CodegenConfig::TYPES), 2612a9d9c8Sopenharmony_ci "vars" => config.insert(CodegenConfig::VARS), 2712a9d9c8Sopenharmony_ci "methods" => config.insert(CodegenConfig::METHODS), 2812a9d9c8Sopenharmony_ci "constructors" => config.insert(CodegenConfig::CONSTRUCTORS), 2912a9d9c8Sopenharmony_ci "destructors" => config.insert(CodegenConfig::DESTRUCTORS), 3012a9d9c8Sopenharmony_ci otherwise => { 3112a9d9c8Sopenharmony_ci return Err(Error::new( 3212a9d9c8Sopenharmony_ci ErrorKind::Other, 3312a9d9c8Sopenharmony_ci format!("Unknown generate item: {}", otherwise), 3412a9d9c8Sopenharmony_ci )); 3512a9d9c8Sopenharmony_ci } 3612a9d9c8Sopenharmony_ci } 3712a9d9c8Sopenharmony_ci } 3812a9d9c8Sopenharmony_ci 3912a9d9c8Sopenharmony_ci Ok(config) 4012a9d9c8Sopenharmony_ci} 4112a9d9c8Sopenharmony_ci 4212a9d9c8Sopenharmony_ci#[derive(Parser, Debug)] 4312a9d9c8Sopenharmony_ci#[clap( 4412a9d9c8Sopenharmony_ci about = "Generates Rust bindings from C/C++ headers.", 4512a9d9c8Sopenharmony_ci override_usage = "bindgen [FLAGS] [OPTIONS] [HEADER] -- [CLANG_ARGS]...", 4612a9d9c8Sopenharmony_ci trailing_var_arg = true 4712a9d9c8Sopenharmony_ci)] 4812a9d9c8Sopenharmony_cistruct BindgenCommand { 4912a9d9c8Sopenharmony_ci /// C or C++ header file. 5012a9d9c8Sopenharmony_ci header: Option<String>, 5112a9d9c8Sopenharmony_ci /// Path to write depfile to. 5212a9d9c8Sopenharmony_ci #[arg(long)] 5312a9d9c8Sopenharmony_ci depfile: Option<String>, 5412a9d9c8Sopenharmony_ci /// The default style of code used to generate enums. 5512a9d9c8Sopenharmony_ci #[arg(long, value_name = "VARIANT")] 5612a9d9c8Sopenharmony_ci default_enum_style: Option<EnumVariation>, 5712a9d9c8Sopenharmony_ci /// Mark any enum whose name matches <REGEX> as a set of bitfield flags. 5812a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 5912a9d9c8Sopenharmony_ci bitfield_enum: Vec<String>, 6012a9d9c8Sopenharmony_ci /// Mark any enum whose name matches <REGEX> as a newtype. 6112a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 6212a9d9c8Sopenharmony_ci newtype_enum: Vec<String>, 6312a9d9c8Sopenharmony_ci /// Mark any enum whose name matches <REGEX> as a global newtype. 6412a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 6512a9d9c8Sopenharmony_ci newtype_global_enum: Vec<String>, 6612a9d9c8Sopenharmony_ci /// Mark any enum whose name matches <REGEX> as a Rust enum. 6712a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 6812a9d9c8Sopenharmony_ci rustified_enum: Vec<String>, 6912a9d9c8Sopenharmony_ci /// Mark any enum whose name matches <REGEX> as a series of constants. 7012a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 7112a9d9c8Sopenharmony_ci constified_enum: Vec<String>, 7212a9d9c8Sopenharmony_ci /// Mark any enum whose name matches <regex> as a module of constants. 7312a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 7412a9d9c8Sopenharmony_ci constified_enum_module: Vec<String>, 7512a9d9c8Sopenharmony_ci /// The default signed/unsigned type for C macro constants. 7612a9d9c8Sopenharmony_ci #[arg(long, value_name = "VARIANT")] 7712a9d9c8Sopenharmony_ci default_macro_constant_type: Option<MacroTypeVariation>, 7812a9d9c8Sopenharmony_ci /// The default style of code used to generate typedefs. 7912a9d9c8Sopenharmony_ci #[arg(long, value_name = "VARIANT")] 8012a9d9c8Sopenharmony_ci default_alias_style: Option<AliasVariation>, 8112a9d9c8Sopenharmony_ci /// Mark any typedef alias whose name matches <REGEX> to use normal type aliasing. 8212a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 8312a9d9c8Sopenharmony_ci normal_alias: Vec<String>, 8412a9d9c8Sopenharmony_ci /// Mark any typedef alias whose name matches <REGEX> to have a new type generated for it. 8512a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 8612a9d9c8Sopenharmony_ci new_type_alias: Vec<String>, 8712a9d9c8Sopenharmony_ci /// Mark any typedef alias whose name matches <REGEX> to have a new type with Deref and DerefMut to the inner type. 8812a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 8912a9d9c8Sopenharmony_ci new_type_alias_deref: Vec<String>, 9012a9d9c8Sopenharmony_ci /// The default style of code used to generate unions with non-Copy members. Note that ManuallyDrop was first stabilized in Rust 1.20.0. 9112a9d9c8Sopenharmony_ci #[arg(long, value_name = "STYLE")] 9212a9d9c8Sopenharmony_ci default_non_copy_union_style: Option<NonCopyUnionStyle>, 9312a9d9c8Sopenharmony_ci /// Mark any union whose name matches <REGEX> and who has a non-Copy member to use a bindgen-generated wrapper for fields. 9412a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 9512a9d9c8Sopenharmony_ci bindgen_wrapper_union: Vec<String>, 9612a9d9c8Sopenharmony_ci /// 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. 9712a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 9812a9d9c8Sopenharmony_ci manually_drop_union: Vec<String>, 9912a9d9c8Sopenharmony_ci /// Mark <TYPE> as hidden. 10012a9d9c8Sopenharmony_ci #[arg(long, value_name = "TYPE")] 10112a9d9c8Sopenharmony_ci blocklist_type: Vec<String>, 10212a9d9c8Sopenharmony_ci /// Mark <FUNCTION> as hidden. 10312a9d9c8Sopenharmony_ci #[arg(long, value_name = "FUNCTION")] 10412a9d9c8Sopenharmony_ci blocklist_function: Vec<String>, 10512a9d9c8Sopenharmony_ci /// Mark <ITEM> as hidden. 10612a9d9c8Sopenharmony_ci #[arg(long, value_name = "ITEM")] 10712a9d9c8Sopenharmony_ci blocklist_item: Vec<String>, 10812a9d9c8Sopenharmony_ci /// Mark <FILE> as hidden. 10912a9d9c8Sopenharmony_ci #[arg(long, value_name = "FILE")] 11012a9d9c8Sopenharmony_ci blocklist_file: Vec<String>, 11112a9d9c8Sopenharmony_ci /// Avoid generating layout tests for any type. 11212a9d9c8Sopenharmony_ci #[arg(long)] 11312a9d9c8Sopenharmony_ci no_layout_tests: bool, 11412a9d9c8Sopenharmony_ci /// Avoid deriving Copy on any type. 11512a9d9c8Sopenharmony_ci #[arg(long)] 11612a9d9c8Sopenharmony_ci no_derive_copy: bool, 11712a9d9c8Sopenharmony_ci /// Avoid deriving Debug on any type. 11812a9d9c8Sopenharmony_ci #[arg(long)] 11912a9d9c8Sopenharmony_ci no_derive_debug: bool, 12012a9d9c8Sopenharmony_ci /// Avoid deriving Default on any type. 12112a9d9c8Sopenharmony_ci #[arg(long, hide = true)] 12212a9d9c8Sopenharmony_ci no_derive_default: bool, 12312a9d9c8Sopenharmony_ci /// Create a Debug implementation if it cannot be derived automatically. 12412a9d9c8Sopenharmony_ci #[arg(long)] 12512a9d9c8Sopenharmony_ci impl_debug: bool, 12612a9d9c8Sopenharmony_ci /// Create a PartialEq implementation if it cannot be derived automatically. 12712a9d9c8Sopenharmony_ci #[arg(long)] 12812a9d9c8Sopenharmony_ci impl_partialeq: bool, 12912a9d9c8Sopenharmony_ci /// Derive Default on any type. 13012a9d9c8Sopenharmony_ci #[arg(long)] 13112a9d9c8Sopenharmony_ci with_derive_default: bool, 13212a9d9c8Sopenharmony_ci /// Derive Hash on any type.docstring 13312a9d9c8Sopenharmony_ci #[arg(long)] 13412a9d9c8Sopenharmony_ci with_derive_hash: bool, 13512a9d9c8Sopenharmony_ci /// Derive PartialEq on any type. 13612a9d9c8Sopenharmony_ci #[arg(long)] 13712a9d9c8Sopenharmony_ci with_derive_partialeq: bool, 13812a9d9c8Sopenharmony_ci /// Derive PartialOrd on any type. 13912a9d9c8Sopenharmony_ci #[arg(long)] 14012a9d9c8Sopenharmony_ci with_derive_partialord: bool, 14112a9d9c8Sopenharmony_ci /// Derive Eq on any type. 14212a9d9c8Sopenharmony_ci #[arg(long)] 14312a9d9c8Sopenharmony_ci with_derive_eq: bool, 14412a9d9c8Sopenharmony_ci /// Derive Ord on any type. 14512a9d9c8Sopenharmony_ci #[arg(long)] 14612a9d9c8Sopenharmony_ci with_derive_ord: bool, 14712a9d9c8Sopenharmony_ci /// Avoid including doc comments in the output, see: https://github.com/rust-lang/rust-bindgen/issues/426 14812a9d9c8Sopenharmony_ci #[arg(long)] 14912a9d9c8Sopenharmony_ci no_doc_comments: bool, 15012a9d9c8Sopenharmony_ci /// 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. 15112a9d9c8Sopenharmony_ci #[arg(long)] 15212a9d9c8Sopenharmony_ci no_recursive_allowlist: bool, 15312a9d9c8Sopenharmony_ci /// Use extern crate instead of use for objc. 15412a9d9c8Sopenharmony_ci #[arg(long)] 15512a9d9c8Sopenharmony_ci objc_extern_crate: bool, 15612a9d9c8Sopenharmony_ci /// Generate block signatures instead of void pointers. 15712a9d9c8Sopenharmony_ci #[arg(long)] 15812a9d9c8Sopenharmony_ci generate_block: bool, 15912a9d9c8Sopenharmony_ci /// Use extern crate instead of use for block. 16012a9d9c8Sopenharmony_ci #[arg(long)] 16112a9d9c8Sopenharmony_ci block_extern_crate: bool, 16212a9d9c8Sopenharmony_ci /// Do not trust the libclang-provided mangling 16312a9d9c8Sopenharmony_ci #[arg(long)] 16412a9d9c8Sopenharmony_ci distrust_clang_mangling: bool, 16512a9d9c8Sopenharmony_ci /// Output bindings for builtin definitions, e.g. __builtin_va_list. 16612a9d9c8Sopenharmony_ci #[arg(long)] 16712a9d9c8Sopenharmony_ci builtins: bool, 16812a9d9c8Sopenharmony_ci /// Use the given prefix before raw types instead of ::std::os::raw. 16912a9d9c8Sopenharmony_ci #[arg(long, value_name = "PREFIX")] 17012a9d9c8Sopenharmony_ci ctypes_prefix: Option<String>, 17112a9d9c8Sopenharmony_ci /// Use the given prefix for anonymous fields. 17212a9d9c8Sopenharmony_ci #[arg(long, default_value = DEFAULT_ANON_FIELDS_PREFIX, value_name = "PREFIX")] 17312a9d9c8Sopenharmony_ci anon_fields_prefix: String, 17412a9d9c8Sopenharmony_ci /// Time the different bindgen phases and print to stderr 17512a9d9c8Sopenharmony_ci #[arg(long)] 17612a9d9c8Sopenharmony_ci time_phases: bool, 17712a9d9c8Sopenharmony_ci /// Output the Clang AST for debugging purposes. 17812a9d9c8Sopenharmony_ci #[arg(long)] 17912a9d9c8Sopenharmony_ci emit_clang_ast: bool, 18012a9d9c8Sopenharmony_ci /// Output our internal IR for debugging purposes. 18112a9d9c8Sopenharmony_ci #[arg(long)] 18212a9d9c8Sopenharmony_ci emit_ir: bool, 18312a9d9c8Sopenharmony_ci /// Dump graphviz dot file. 18412a9d9c8Sopenharmony_ci #[arg(long, value_name = "PATH")] 18512a9d9c8Sopenharmony_ci emit_ir_graphviz: Option<String>, 18612a9d9c8Sopenharmony_ci /// Enable support for C++ namespaces. 18712a9d9c8Sopenharmony_ci #[arg(long)] 18812a9d9c8Sopenharmony_ci enable_cxx_namespaces: bool, 18912a9d9c8Sopenharmony_ci /// Disable namespacing via mangling, causing bindgen to generate names like `Baz` instead of `foo_bar_Baz` for an input name `foo::bar::Baz`. 19012a9d9c8Sopenharmony_ci #[arg(long)] 19112a9d9c8Sopenharmony_ci disable_name_namespacing: bool, 19212a9d9c8Sopenharmony_ci /// Disable nested struct naming, causing bindgen to generate names like `bar` instead of `foo_bar` for a nested definition `struct foo { struct bar { } b; };`. 19312a9d9c8Sopenharmony_ci #[arg(long)] 19412a9d9c8Sopenharmony_ci disable_nested_struct_naming: bool, 19512a9d9c8Sopenharmony_ci /// Disable support for native Rust unions. 19612a9d9c8Sopenharmony_ci #[arg(long)] 19712a9d9c8Sopenharmony_ci disable_untagged_union: bool, 19812a9d9c8Sopenharmony_ci /// Suppress insertion of bindgen's version identifier into generated bindings. 19912a9d9c8Sopenharmony_ci #[arg(long)] 20012a9d9c8Sopenharmony_ci disable_header_comment: bool, 20112a9d9c8Sopenharmony_ci /// Do not generate bindings for functions or methods. This is useful when you only care about struct layouts.docstring 20212a9d9c8Sopenharmony_ci #[arg(long)] 20312a9d9c8Sopenharmony_ci ignore_functions: bool, 20412a9d9c8Sopenharmony_ci /// Generate only given items, split by commas. Valid values are `functions`,`types`, `vars`, `methods`, `constructors` and `destructors`. 20512a9d9c8Sopenharmony_ci #[arg(long, value_parser = parse_codegen_config)] 20612a9d9c8Sopenharmony_ci generate: Option<CodegenConfig>, 20712a9d9c8Sopenharmony_ci /// Do not generate bindings for methods. 20812a9d9c8Sopenharmony_ci #[arg(long)] 20912a9d9c8Sopenharmony_ci ignore_methods: bool, 21012a9d9c8Sopenharmony_ci /// Do not automatically convert floats to f32/f64. 21112a9d9c8Sopenharmony_ci #[arg(long)] 21212a9d9c8Sopenharmony_ci no_convert_floats: bool, 21312a9d9c8Sopenharmony_ci /// Do not prepend the enum name to constant or newtype variants. 21412a9d9c8Sopenharmony_ci #[arg(long)] 21512a9d9c8Sopenharmony_ci no_prepend_enum_name: bool, 21612a9d9c8Sopenharmony_ci /// Do not try to detect default include paths 21712a9d9c8Sopenharmony_ci #[arg(long)] 21812a9d9c8Sopenharmony_ci no_include_path_detection: bool, 21912a9d9c8Sopenharmony_ci /// Try to fit macro constants into types smaller than u32/i32 22012a9d9c8Sopenharmony_ci #[arg(long)] 22112a9d9c8Sopenharmony_ci fit_macro_constant_types: bool, 22212a9d9c8Sopenharmony_ci /// Mark <TYPE> as opaque. 22312a9d9c8Sopenharmony_ci #[arg(long, value_name = "TYPE")] 22412a9d9c8Sopenharmony_ci opaque_type: Vec<String>, 22512a9d9c8Sopenharmony_ci /// Write Rust bindings to <OUTPUT>. 22612a9d9c8Sopenharmony_ci #[arg(long, short, value_name = "OUTPUT")] 22712a9d9c8Sopenharmony_ci output: Option<String>, 22812a9d9c8Sopenharmony_ci /// Add a raw line of Rust code at the beginning of output. 22912a9d9c8Sopenharmony_ci #[arg(long)] 23012a9d9c8Sopenharmony_ci raw_line: Vec<String>, 23112a9d9c8Sopenharmony_ci /// Add a raw line of Rust code to a given module. 23212a9d9c8Sopenharmony_ci #[arg(long, number_of_values = 2, value_names = ["MODULE-NAME", "RAW-LINE"])] 23312a9d9c8Sopenharmony_ci module_raw_line: Vec<String>, 23412a9d9c8Sopenharmony_ci #[arg(long, help = rust_target_help())] 23512a9d9c8Sopenharmony_ci rust_target: Option<RustTarget>, 23612a9d9c8Sopenharmony_ci /// Use types from Rust core instead of std. 23712a9d9c8Sopenharmony_ci #[arg(long)] 23812a9d9c8Sopenharmony_ci use_core: bool, 23912a9d9c8Sopenharmony_ci /// Conservatively generate inline namespaces to avoid name conflicts. 24012a9d9c8Sopenharmony_ci #[arg(long)] 24112a9d9c8Sopenharmony_ci conservative_inline_namespaces: bool, 24212a9d9c8Sopenharmony_ci /// MSVC C++ ABI mangling. DEPRECATED: Has no effect. 24312a9d9c8Sopenharmony_ci #[arg(long)] 24412a9d9c8Sopenharmony_ci use_msvc_mangling: bool, 24512a9d9c8Sopenharmony_ci /// Allowlist all the free-standing functions matching <REGEX>. Other non-allowlisted functions will not be generated. 24612a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 24712a9d9c8Sopenharmony_ci allowlist_function: Vec<String>, 24812a9d9c8Sopenharmony_ci /// Generate inline functions. 24912a9d9c8Sopenharmony_ci #[arg(long)] 25012a9d9c8Sopenharmony_ci generate_inline_functions: bool, 25112a9d9c8Sopenharmony_ci /// Only generate types matching <REGEX>. Other non-allowlisted types will not be generated. 25212a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 25312a9d9c8Sopenharmony_ci allowlist_type: Vec<String>, 25412a9d9c8Sopenharmony_ci /// Allowlist all the free-standing variables matching <REGEX>. Other non-allowlisted variables will not be generated. 25512a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 25612a9d9c8Sopenharmony_ci allowlist_var: Vec<String>, 25712a9d9c8Sopenharmony_ci /// Allowlist all contents of <PATH>. 25812a9d9c8Sopenharmony_ci #[arg(long, value_name = "PATH")] 25912a9d9c8Sopenharmony_ci allowlist_file: Vec<String>, 26012a9d9c8Sopenharmony_ci /// Print verbose error messages. 26112a9d9c8Sopenharmony_ci #[arg(long)] 26212a9d9c8Sopenharmony_ci verbose: bool, 26312a9d9c8Sopenharmony_ci /// 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`. 26412a9d9c8Sopenharmony_ci #[arg(long)] 26512a9d9c8Sopenharmony_ci dump_preprocessed_input: bool, 26612a9d9c8Sopenharmony_ci /// Do not record matching items in the regex sets. This disables reporting of unused items. 26712a9d9c8Sopenharmony_ci #[arg(long)] 26812a9d9c8Sopenharmony_ci no_record_matches: bool, 26912a9d9c8Sopenharmony_ci /// Ignored - this is enabled by default. 27012a9d9c8Sopenharmony_ci #[arg(long = "size_t-is-usize")] 27112a9d9c8Sopenharmony_ci size_t_is_usize: bool, 27212a9d9c8Sopenharmony_ci /// Do not bind size_t as usize (useful on platforms where those types are incompatible). 27312a9d9c8Sopenharmony_ci #[arg(long = "no-size_t-is-usize")] 27412a9d9c8Sopenharmony_ci no_size_t_is_usize: bool, 27512a9d9c8Sopenharmony_ci /// Do not format the generated bindings with rustfmt. 27612a9d9c8Sopenharmony_ci #[arg(long)] 27712a9d9c8Sopenharmony_ci no_rustfmt_bindings: bool, 27812a9d9c8Sopenharmony_ci /// Format the generated bindings with rustfmt. DEPRECATED: --rustfmt-bindings is now enabled by default. Disable with --no-rustfmt-bindings. 27912a9d9c8Sopenharmony_ci #[arg(long)] 28012a9d9c8Sopenharmony_ci rustfmt_bindings: bool, 28112a9d9c8Sopenharmony_ci /// The absolute path to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter is incompatible with --no-rustfmt-bindings. 28212a9d9c8Sopenharmony_ci #[arg(long, value_name = "PATH")] 28312a9d9c8Sopenharmony_ci rustfmt_configuration_file: Option<String>, 28412a9d9c8Sopenharmony_ci /// Avoid deriving PartialEq for types matching <REGEX>. 28512a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 28612a9d9c8Sopenharmony_ci no_partialeq: Vec<String>, 28712a9d9c8Sopenharmony_ci /// Avoid deriving Copy for types matching <REGEX>. 28812a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 28912a9d9c8Sopenharmony_ci no_copy: Vec<String>, 29012a9d9c8Sopenharmony_ci /// Avoid deriving Debug for types matching <REGEX>. 29112a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 29212a9d9c8Sopenharmony_ci no_debug: Vec<String>, 29312a9d9c8Sopenharmony_ci /// Avoid deriving/implementing Default for types matching <REGEX>. 29412a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 29512a9d9c8Sopenharmony_ci no_default: Vec<String>, 29612a9d9c8Sopenharmony_ci /// Avoid deriving Hash for types matching <REGEX>. 29712a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 29812a9d9c8Sopenharmony_ci no_hash: Vec<String>, 29912a9d9c8Sopenharmony_ci /// Add #[must_use] annotation to types matching <REGEX>. 30012a9d9c8Sopenharmony_ci #[arg(long, value_name = "REGEX")] 30112a9d9c8Sopenharmony_ci must_use_type: Vec<String>, 30212a9d9c8Sopenharmony_ci /// Enables detecting unexposed attributes in functions (slow). Used to generate #[must_use] annotations. 30312a9d9c8Sopenharmony_ci #[arg(long)] 30412a9d9c8Sopenharmony_ci enable_function_attribute_detection: bool, 30512a9d9c8Sopenharmony_ci /// Use `*const [T; size]` instead of `*const T` for C arrays 30612a9d9c8Sopenharmony_ci #[arg(long)] 30712a9d9c8Sopenharmony_ci use_array_pointers_in_arguments: bool, 30812a9d9c8Sopenharmony_ci /// The name to be used in a #[link(wasm_import_module = ...)] statement 30912a9d9c8Sopenharmony_ci #[arg(long, value_name = "NAME")] 31012a9d9c8Sopenharmony_ci wasm_import_module_name: Option<String>, 31112a9d9c8Sopenharmony_ci /// Use dynamic loading mode with the given library name. 31212a9d9c8Sopenharmony_ci #[arg(long, value_name = "NAME")] 31312a9d9c8Sopenharmony_ci dynamic_loading: Option<String>, 31412a9d9c8Sopenharmony_ci /// Require successful linkage to all functions in the library. 31512a9d9c8Sopenharmony_ci #[arg(long)] 31612a9d9c8Sopenharmony_ci dynamic_link_require_all: bool, 31712a9d9c8Sopenharmony_ci /// Makes generated bindings `pub` only for items if the items are publically accessible in C++. 31812a9d9c8Sopenharmony_ci #[arg(long)] 31912a9d9c8Sopenharmony_ci respect_cxx_access_specs: bool, 32012a9d9c8Sopenharmony_ci /// Always translate enum integer types to native Rust integer types. 32112a9d9c8Sopenharmony_ci #[arg(long)] 32212a9d9c8Sopenharmony_ci translate_enum_integer_types: bool, 32312a9d9c8Sopenharmony_ci /// Generate types with C style naming. 32412a9d9c8Sopenharmony_ci #[arg(long)] 32512a9d9c8Sopenharmony_ci c_naming: bool, 32612a9d9c8Sopenharmony_ci /// Always output explicit padding fields. 32712a9d9c8Sopenharmony_ci #[arg(long)] 32812a9d9c8Sopenharmony_ci explicit_padding: bool, 32912a9d9c8Sopenharmony_ci /// Enables generation of vtable functions. 33012a9d9c8Sopenharmony_ci #[arg(long)] 33112a9d9c8Sopenharmony_ci vtable_generation: bool, 33212a9d9c8Sopenharmony_ci /// Enables sorting of code generation in a predefined manner. 33312a9d9c8Sopenharmony_ci #[arg(long)] 33412a9d9c8Sopenharmony_ci sort_semantically: bool, 33512a9d9c8Sopenharmony_ci /// Deduplicates extern blocks. 33612a9d9c8Sopenharmony_ci #[arg(long)] 33712a9d9c8Sopenharmony_ci merge_extern_blocks: bool, 33812a9d9c8Sopenharmony_ci /// 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, fastcall, thiscall, aapcs, win64 or C-unwind. 33912a9d9c8Sopenharmony_ci #[arg(long, value_name = "OVERRIDE")] 34012a9d9c8Sopenharmony_ci override_abi: Vec<String>, 34112a9d9c8Sopenharmony_ci /// Wrap unsafe operations in unsafe blocks. 34212a9d9c8Sopenharmony_ci #[arg(long)] 34312a9d9c8Sopenharmony_ci wrap_unsafe_ops: bool, 34412a9d9c8Sopenharmony_ci /// 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. 34512a9d9c8Sopenharmony_ci #[arg(long, value_name = "CUSTOM")] 34612a9d9c8Sopenharmony_ci with_derive_custom: Vec<String>, 34712a9d9c8Sopenharmony_ci /// 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. 34812a9d9c8Sopenharmony_ci #[arg(long, value_name = "CUSTOM")] 34912a9d9c8Sopenharmony_ci with_derive_custom_struct: Vec<String>, 35012a9d9c8Sopenharmony_ci /// 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. 35112a9d9c8Sopenharmony_ci #[arg(long, value_name = "CUSTOM")] 35212a9d9c8Sopenharmony_ci with_derive_custom_enum: Vec<String>, 35312a9d9c8Sopenharmony_ci /// 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. 35412a9d9c8Sopenharmony_ci #[arg(long, value_name = "CUSTOM")] 35512a9d9c8Sopenharmony_ci with_derive_custom_union: Vec<String>, 35612a9d9c8Sopenharmony_ci /// Generate wrappers for `static` and `static inline` functions. 35712a9d9c8Sopenharmony_ci #[arg(long, requires = "experimental")] 35812a9d9c8Sopenharmony_ci wrap_static_fns: bool, 35912a9d9c8Sopenharmony_ci /// Sets the path for the source file that must be created due to the presence of `static` and 36012a9d9c8Sopenharmony_ci /// `static inline` functions. 36112a9d9c8Sopenharmony_ci #[arg(long, requires = "experimental", value_name = "PATH")] 36212a9d9c8Sopenharmony_ci wrap_static_fns_path: Option<PathBuf>, 36312a9d9c8Sopenharmony_ci /// Sets the suffix added to the extern wrapper functions generated for `static` and `static 36412a9d9c8Sopenharmony_ci /// inline` functions. 36512a9d9c8Sopenharmony_ci #[arg(long, requires = "experimental", value_name = "SUFFIX")] 36612a9d9c8Sopenharmony_ci wrap_static_fns_suffix: Option<String>, 36712a9d9c8Sopenharmony_ci /// Enables experimental features. 36812a9d9c8Sopenharmony_ci #[arg(long)] 36912a9d9c8Sopenharmony_ci experimental: bool, 37012a9d9c8Sopenharmony_ci /// Prints the version, and exits 37112a9d9c8Sopenharmony_ci #[arg(short = 'V', long)] 37212a9d9c8Sopenharmony_ci version: bool, 37312a9d9c8Sopenharmony_ci /// Arguments to be passed straight through to clang. 37412a9d9c8Sopenharmony_ci clang_args: Vec<String>, 37512a9d9c8Sopenharmony_ci} 37612a9d9c8Sopenharmony_ci 37712a9d9c8Sopenharmony_ci/// Construct a new [`Builder`](./struct.Builder.html) from command line flags. 37812a9d9c8Sopenharmony_cipub fn builder_from_flags<I>( 37912a9d9c8Sopenharmony_ci args: I, 38012a9d9c8Sopenharmony_ci) -> Result<(Builder, Box<dyn io::Write>, bool), io::Error> 38112a9d9c8Sopenharmony_ciwhere 38212a9d9c8Sopenharmony_ci I: Iterator<Item = String>, 38312a9d9c8Sopenharmony_ci{ 38412a9d9c8Sopenharmony_ci let command = BindgenCommand::parse_from(args); 38512a9d9c8Sopenharmony_ci 38612a9d9c8Sopenharmony_ci let BindgenCommand { 38712a9d9c8Sopenharmony_ci header, 38812a9d9c8Sopenharmony_ci depfile, 38912a9d9c8Sopenharmony_ci default_enum_style, 39012a9d9c8Sopenharmony_ci bitfield_enum, 39112a9d9c8Sopenharmony_ci newtype_enum, 39212a9d9c8Sopenharmony_ci newtype_global_enum, 39312a9d9c8Sopenharmony_ci rustified_enum, 39412a9d9c8Sopenharmony_ci constified_enum, 39512a9d9c8Sopenharmony_ci constified_enum_module, 39612a9d9c8Sopenharmony_ci default_macro_constant_type, 39712a9d9c8Sopenharmony_ci default_alias_style, 39812a9d9c8Sopenharmony_ci normal_alias, 39912a9d9c8Sopenharmony_ci new_type_alias, 40012a9d9c8Sopenharmony_ci new_type_alias_deref, 40112a9d9c8Sopenharmony_ci default_non_copy_union_style, 40212a9d9c8Sopenharmony_ci bindgen_wrapper_union, 40312a9d9c8Sopenharmony_ci manually_drop_union, 40412a9d9c8Sopenharmony_ci blocklist_type, 40512a9d9c8Sopenharmony_ci blocklist_function, 40612a9d9c8Sopenharmony_ci blocklist_item, 40712a9d9c8Sopenharmony_ci blocklist_file, 40812a9d9c8Sopenharmony_ci no_layout_tests, 40912a9d9c8Sopenharmony_ci no_derive_copy, 41012a9d9c8Sopenharmony_ci no_derive_debug, 41112a9d9c8Sopenharmony_ci no_derive_default, 41212a9d9c8Sopenharmony_ci impl_debug, 41312a9d9c8Sopenharmony_ci impl_partialeq, 41412a9d9c8Sopenharmony_ci with_derive_default, 41512a9d9c8Sopenharmony_ci with_derive_hash, 41612a9d9c8Sopenharmony_ci with_derive_partialeq, 41712a9d9c8Sopenharmony_ci with_derive_partialord, 41812a9d9c8Sopenharmony_ci with_derive_eq, 41912a9d9c8Sopenharmony_ci with_derive_ord, 42012a9d9c8Sopenharmony_ci no_doc_comments, 42112a9d9c8Sopenharmony_ci no_recursive_allowlist, 42212a9d9c8Sopenharmony_ci objc_extern_crate, 42312a9d9c8Sopenharmony_ci generate_block, 42412a9d9c8Sopenharmony_ci block_extern_crate, 42512a9d9c8Sopenharmony_ci distrust_clang_mangling, 42612a9d9c8Sopenharmony_ci builtins, 42712a9d9c8Sopenharmony_ci ctypes_prefix, 42812a9d9c8Sopenharmony_ci anon_fields_prefix, 42912a9d9c8Sopenharmony_ci time_phases, 43012a9d9c8Sopenharmony_ci emit_clang_ast, 43112a9d9c8Sopenharmony_ci emit_ir, 43212a9d9c8Sopenharmony_ci emit_ir_graphviz, 43312a9d9c8Sopenharmony_ci enable_cxx_namespaces, 43412a9d9c8Sopenharmony_ci disable_name_namespacing, 43512a9d9c8Sopenharmony_ci disable_nested_struct_naming, 43612a9d9c8Sopenharmony_ci disable_untagged_union, 43712a9d9c8Sopenharmony_ci disable_header_comment, 43812a9d9c8Sopenharmony_ci ignore_functions, 43912a9d9c8Sopenharmony_ci generate, 44012a9d9c8Sopenharmony_ci ignore_methods, 44112a9d9c8Sopenharmony_ci no_convert_floats, 44212a9d9c8Sopenharmony_ci no_prepend_enum_name, 44312a9d9c8Sopenharmony_ci no_include_path_detection, 44412a9d9c8Sopenharmony_ci fit_macro_constant_types, 44512a9d9c8Sopenharmony_ci opaque_type, 44612a9d9c8Sopenharmony_ci output, 44712a9d9c8Sopenharmony_ci raw_line, 44812a9d9c8Sopenharmony_ci module_raw_line, 44912a9d9c8Sopenharmony_ci rust_target, 45012a9d9c8Sopenharmony_ci use_core, 45112a9d9c8Sopenharmony_ci conservative_inline_namespaces, 45212a9d9c8Sopenharmony_ci use_msvc_mangling: _, 45312a9d9c8Sopenharmony_ci allowlist_function, 45412a9d9c8Sopenharmony_ci generate_inline_functions, 45512a9d9c8Sopenharmony_ci allowlist_type, 45612a9d9c8Sopenharmony_ci allowlist_var, 45712a9d9c8Sopenharmony_ci allowlist_file, 45812a9d9c8Sopenharmony_ci verbose, 45912a9d9c8Sopenharmony_ci dump_preprocessed_input, 46012a9d9c8Sopenharmony_ci no_record_matches, 46112a9d9c8Sopenharmony_ci size_t_is_usize: _, 46212a9d9c8Sopenharmony_ci no_size_t_is_usize, 46312a9d9c8Sopenharmony_ci no_rustfmt_bindings, 46412a9d9c8Sopenharmony_ci rustfmt_bindings: _, 46512a9d9c8Sopenharmony_ci rustfmt_configuration_file, 46612a9d9c8Sopenharmony_ci no_partialeq, 46712a9d9c8Sopenharmony_ci no_copy, 46812a9d9c8Sopenharmony_ci no_debug, 46912a9d9c8Sopenharmony_ci no_default, 47012a9d9c8Sopenharmony_ci no_hash, 47112a9d9c8Sopenharmony_ci must_use_type, 47212a9d9c8Sopenharmony_ci enable_function_attribute_detection, 47312a9d9c8Sopenharmony_ci use_array_pointers_in_arguments, 47412a9d9c8Sopenharmony_ci wasm_import_module_name, 47512a9d9c8Sopenharmony_ci dynamic_loading, 47612a9d9c8Sopenharmony_ci dynamic_link_require_all, 47712a9d9c8Sopenharmony_ci respect_cxx_access_specs, 47812a9d9c8Sopenharmony_ci translate_enum_integer_types, 47912a9d9c8Sopenharmony_ci c_naming, 48012a9d9c8Sopenharmony_ci explicit_padding, 48112a9d9c8Sopenharmony_ci vtable_generation, 48212a9d9c8Sopenharmony_ci sort_semantically, 48312a9d9c8Sopenharmony_ci merge_extern_blocks, 48412a9d9c8Sopenharmony_ci override_abi, 48512a9d9c8Sopenharmony_ci wrap_unsafe_ops, 48612a9d9c8Sopenharmony_ci with_derive_custom, 48712a9d9c8Sopenharmony_ci with_derive_custom_struct, 48812a9d9c8Sopenharmony_ci with_derive_custom_enum, 48912a9d9c8Sopenharmony_ci with_derive_custom_union, 49012a9d9c8Sopenharmony_ci wrap_static_fns, 49112a9d9c8Sopenharmony_ci wrap_static_fns_path, 49212a9d9c8Sopenharmony_ci wrap_static_fns_suffix, 49312a9d9c8Sopenharmony_ci experimental: _, 49412a9d9c8Sopenharmony_ci version, 49512a9d9c8Sopenharmony_ci clang_args, 49612a9d9c8Sopenharmony_ci } = command; 49712a9d9c8Sopenharmony_ci 49812a9d9c8Sopenharmony_ci if version { 49912a9d9c8Sopenharmony_ci println!( 50012a9d9c8Sopenharmony_ci "bindgen {}", 50112a9d9c8Sopenharmony_ci option_env!("CARGO_PKG_VERSION").unwrap_or("unknown") 50212a9d9c8Sopenharmony_ci ); 50312a9d9c8Sopenharmony_ci if verbose { 50412a9d9c8Sopenharmony_ci println!("Clang: {}", bindgen::clang_version().full); 50512a9d9c8Sopenharmony_ci } 50612a9d9c8Sopenharmony_ci std::process::exit(0); 50712a9d9c8Sopenharmony_ci } 50812a9d9c8Sopenharmony_ci 50912a9d9c8Sopenharmony_ci let mut builder = builder(); 51012a9d9c8Sopenharmony_ci 51112a9d9c8Sopenharmony_ci if let Some(header) = header { 51212a9d9c8Sopenharmony_ci builder = builder.header(header); 51312a9d9c8Sopenharmony_ci } else { 51412a9d9c8Sopenharmony_ci return Err(Error::new(ErrorKind::Other, "Header not found")); 51512a9d9c8Sopenharmony_ci } 51612a9d9c8Sopenharmony_ci 51712a9d9c8Sopenharmony_ci if let Some(rust_target) = rust_target { 51812a9d9c8Sopenharmony_ci builder = builder.rust_target(rust_target); 51912a9d9c8Sopenharmony_ci } 52012a9d9c8Sopenharmony_ci 52112a9d9c8Sopenharmony_ci if let Some(variant) = default_enum_style { 52212a9d9c8Sopenharmony_ci builder = builder.default_enum_style(variant); 52312a9d9c8Sopenharmony_ci } 52412a9d9c8Sopenharmony_ci 52512a9d9c8Sopenharmony_ci for regex in bitfield_enum { 52612a9d9c8Sopenharmony_ci builder = builder.bitfield_enum(regex); 52712a9d9c8Sopenharmony_ci } 52812a9d9c8Sopenharmony_ci 52912a9d9c8Sopenharmony_ci for regex in newtype_enum { 53012a9d9c8Sopenharmony_ci builder = builder.newtype_enum(regex); 53112a9d9c8Sopenharmony_ci } 53212a9d9c8Sopenharmony_ci 53312a9d9c8Sopenharmony_ci for regex in newtype_global_enum { 53412a9d9c8Sopenharmony_ci builder = builder.newtype_global_enum(regex); 53512a9d9c8Sopenharmony_ci } 53612a9d9c8Sopenharmony_ci 53712a9d9c8Sopenharmony_ci for regex in rustified_enum { 53812a9d9c8Sopenharmony_ci builder = builder.rustified_enum(regex); 53912a9d9c8Sopenharmony_ci } 54012a9d9c8Sopenharmony_ci 54112a9d9c8Sopenharmony_ci for regex in constified_enum { 54212a9d9c8Sopenharmony_ci builder = builder.constified_enum(regex); 54312a9d9c8Sopenharmony_ci } 54412a9d9c8Sopenharmony_ci 54512a9d9c8Sopenharmony_ci for regex in constified_enum_module { 54612a9d9c8Sopenharmony_ci builder = builder.constified_enum_module(regex); 54712a9d9c8Sopenharmony_ci } 54812a9d9c8Sopenharmony_ci 54912a9d9c8Sopenharmony_ci if let Some(default_macro_constant_type) = default_macro_constant_type { 55012a9d9c8Sopenharmony_ci builder = 55112a9d9c8Sopenharmony_ci builder.default_macro_constant_type(default_macro_constant_type) 55212a9d9c8Sopenharmony_ci } 55312a9d9c8Sopenharmony_ci 55412a9d9c8Sopenharmony_ci if let Some(variant) = default_alias_style { 55512a9d9c8Sopenharmony_ci builder = builder.default_alias_style(variant); 55612a9d9c8Sopenharmony_ci } 55712a9d9c8Sopenharmony_ci 55812a9d9c8Sopenharmony_ci for regex in normal_alias { 55912a9d9c8Sopenharmony_ci builder = builder.type_alias(regex); 56012a9d9c8Sopenharmony_ci } 56112a9d9c8Sopenharmony_ci 56212a9d9c8Sopenharmony_ci for regex in new_type_alias { 56312a9d9c8Sopenharmony_ci builder = builder.new_type_alias(regex); 56412a9d9c8Sopenharmony_ci } 56512a9d9c8Sopenharmony_ci 56612a9d9c8Sopenharmony_ci for regex in new_type_alias_deref { 56712a9d9c8Sopenharmony_ci builder = builder.new_type_alias_deref(regex); 56812a9d9c8Sopenharmony_ci } 56912a9d9c8Sopenharmony_ci 57012a9d9c8Sopenharmony_ci if let Some(variant) = default_non_copy_union_style { 57112a9d9c8Sopenharmony_ci builder = builder.default_non_copy_union_style(variant); 57212a9d9c8Sopenharmony_ci } 57312a9d9c8Sopenharmony_ci 57412a9d9c8Sopenharmony_ci for regex in bindgen_wrapper_union { 57512a9d9c8Sopenharmony_ci builder = builder.bindgen_wrapper_union(regex); 57612a9d9c8Sopenharmony_ci } 57712a9d9c8Sopenharmony_ci 57812a9d9c8Sopenharmony_ci for regex in manually_drop_union { 57912a9d9c8Sopenharmony_ci builder = builder.manually_drop_union(regex); 58012a9d9c8Sopenharmony_ci } 58112a9d9c8Sopenharmony_ci 58212a9d9c8Sopenharmony_ci for ty in blocklist_type { 58312a9d9c8Sopenharmony_ci builder = builder.blocklist_type(ty); 58412a9d9c8Sopenharmony_ci } 58512a9d9c8Sopenharmony_ci 58612a9d9c8Sopenharmony_ci for fun in blocklist_function { 58712a9d9c8Sopenharmony_ci builder = builder.blocklist_function(fun); 58812a9d9c8Sopenharmony_ci } 58912a9d9c8Sopenharmony_ci 59012a9d9c8Sopenharmony_ci for id in blocklist_item { 59112a9d9c8Sopenharmony_ci builder = builder.blocklist_item(id); 59212a9d9c8Sopenharmony_ci } 59312a9d9c8Sopenharmony_ci 59412a9d9c8Sopenharmony_ci for file in blocklist_file { 59512a9d9c8Sopenharmony_ci builder = builder.blocklist_file(file); 59612a9d9c8Sopenharmony_ci } 59712a9d9c8Sopenharmony_ci 59812a9d9c8Sopenharmony_ci if builtins { 59912a9d9c8Sopenharmony_ci builder = builder.emit_builtins(); 60012a9d9c8Sopenharmony_ci } 60112a9d9c8Sopenharmony_ci 60212a9d9c8Sopenharmony_ci if no_layout_tests { 60312a9d9c8Sopenharmony_ci builder = builder.layout_tests(false); 60412a9d9c8Sopenharmony_ci } 60512a9d9c8Sopenharmony_ci 60612a9d9c8Sopenharmony_ci if no_derive_copy { 60712a9d9c8Sopenharmony_ci builder = builder.derive_copy(false); 60812a9d9c8Sopenharmony_ci } 60912a9d9c8Sopenharmony_ci 61012a9d9c8Sopenharmony_ci if no_derive_debug { 61112a9d9c8Sopenharmony_ci builder = builder.derive_debug(false); 61212a9d9c8Sopenharmony_ci } 61312a9d9c8Sopenharmony_ci 61412a9d9c8Sopenharmony_ci if impl_debug { 61512a9d9c8Sopenharmony_ci builder = builder.impl_debug(true); 61612a9d9c8Sopenharmony_ci } 61712a9d9c8Sopenharmony_ci 61812a9d9c8Sopenharmony_ci if impl_partialeq { 61912a9d9c8Sopenharmony_ci builder = builder.impl_partialeq(true); 62012a9d9c8Sopenharmony_ci } 62112a9d9c8Sopenharmony_ci 62212a9d9c8Sopenharmony_ci if with_derive_default { 62312a9d9c8Sopenharmony_ci builder = builder.derive_default(true); 62412a9d9c8Sopenharmony_ci } 62512a9d9c8Sopenharmony_ci 62612a9d9c8Sopenharmony_ci if with_derive_hash { 62712a9d9c8Sopenharmony_ci builder = builder.derive_hash(true); 62812a9d9c8Sopenharmony_ci } 62912a9d9c8Sopenharmony_ci 63012a9d9c8Sopenharmony_ci if with_derive_partialeq { 63112a9d9c8Sopenharmony_ci builder = builder.derive_partialeq(true); 63212a9d9c8Sopenharmony_ci } 63312a9d9c8Sopenharmony_ci 63412a9d9c8Sopenharmony_ci if with_derive_partialord { 63512a9d9c8Sopenharmony_ci builder = builder.derive_partialord(true); 63612a9d9c8Sopenharmony_ci } 63712a9d9c8Sopenharmony_ci 63812a9d9c8Sopenharmony_ci if with_derive_eq { 63912a9d9c8Sopenharmony_ci builder = builder.derive_eq(true); 64012a9d9c8Sopenharmony_ci } 64112a9d9c8Sopenharmony_ci 64212a9d9c8Sopenharmony_ci if with_derive_ord { 64312a9d9c8Sopenharmony_ci builder = builder.derive_ord(true); 64412a9d9c8Sopenharmony_ci } 64512a9d9c8Sopenharmony_ci 64612a9d9c8Sopenharmony_ci if no_derive_default { 64712a9d9c8Sopenharmony_ci builder = builder.derive_default(false); 64812a9d9c8Sopenharmony_ci } 64912a9d9c8Sopenharmony_ci 65012a9d9c8Sopenharmony_ci if no_prepend_enum_name { 65112a9d9c8Sopenharmony_ci builder = builder.prepend_enum_name(false); 65212a9d9c8Sopenharmony_ci } 65312a9d9c8Sopenharmony_ci 65412a9d9c8Sopenharmony_ci if no_include_path_detection { 65512a9d9c8Sopenharmony_ci builder = builder.detect_include_paths(false); 65612a9d9c8Sopenharmony_ci } 65712a9d9c8Sopenharmony_ci 65812a9d9c8Sopenharmony_ci if fit_macro_constant_types { 65912a9d9c8Sopenharmony_ci builder = builder.fit_macro_constants(true); 66012a9d9c8Sopenharmony_ci } 66112a9d9c8Sopenharmony_ci 66212a9d9c8Sopenharmony_ci if time_phases { 66312a9d9c8Sopenharmony_ci builder = builder.time_phases(true); 66412a9d9c8Sopenharmony_ci } 66512a9d9c8Sopenharmony_ci 66612a9d9c8Sopenharmony_ci if use_array_pointers_in_arguments { 66712a9d9c8Sopenharmony_ci builder = builder.array_pointers_in_arguments(true); 66812a9d9c8Sopenharmony_ci } 66912a9d9c8Sopenharmony_ci 67012a9d9c8Sopenharmony_ci if let Some(wasm_import_name) = wasm_import_module_name { 67112a9d9c8Sopenharmony_ci builder = builder.wasm_import_module_name(wasm_import_name); 67212a9d9c8Sopenharmony_ci } 67312a9d9c8Sopenharmony_ci 67412a9d9c8Sopenharmony_ci if let Some(prefix) = ctypes_prefix { 67512a9d9c8Sopenharmony_ci builder = builder.ctypes_prefix(prefix); 67612a9d9c8Sopenharmony_ci } 67712a9d9c8Sopenharmony_ci 67812a9d9c8Sopenharmony_ci builder = builder.anon_fields_prefix(anon_fields_prefix); 67912a9d9c8Sopenharmony_ci 68012a9d9c8Sopenharmony_ci if let Some(config) = generate { 68112a9d9c8Sopenharmony_ci builder = builder.with_codegen_config(config); 68212a9d9c8Sopenharmony_ci } 68312a9d9c8Sopenharmony_ci 68412a9d9c8Sopenharmony_ci if emit_clang_ast { 68512a9d9c8Sopenharmony_ci builder = builder.emit_clang_ast(); 68612a9d9c8Sopenharmony_ci } 68712a9d9c8Sopenharmony_ci 68812a9d9c8Sopenharmony_ci if emit_ir { 68912a9d9c8Sopenharmony_ci builder = builder.emit_ir(); 69012a9d9c8Sopenharmony_ci } 69112a9d9c8Sopenharmony_ci 69212a9d9c8Sopenharmony_ci if let Some(path) = emit_ir_graphviz { 69312a9d9c8Sopenharmony_ci builder = builder.emit_ir_graphviz(path); 69412a9d9c8Sopenharmony_ci } 69512a9d9c8Sopenharmony_ci 69612a9d9c8Sopenharmony_ci if enable_cxx_namespaces { 69712a9d9c8Sopenharmony_ci builder = builder.enable_cxx_namespaces(); 69812a9d9c8Sopenharmony_ci } 69912a9d9c8Sopenharmony_ci 70012a9d9c8Sopenharmony_ci if enable_function_attribute_detection { 70112a9d9c8Sopenharmony_ci builder = builder.enable_function_attribute_detection(); 70212a9d9c8Sopenharmony_ci } 70312a9d9c8Sopenharmony_ci 70412a9d9c8Sopenharmony_ci if disable_name_namespacing { 70512a9d9c8Sopenharmony_ci builder = builder.disable_name_namespacing(); 70612a9d9c8Sopenharmony_ci } 70712a9d9c8Sopenharmony_ci 70812a9d9c8Sopenharmony_ci if disable_nested_struct_naming { 70912a9d9c8Sopenharmony_ci builder = builder.disable_nested_struct_naming(); 71012a9d9c8Sopenharmony_ci } 71112a9d9c8Sopenharmony_ci 71212a9d9c8Sopenharmony_ci if disable_untagged_union { 71312a9d9c8Sopenharmony_ci builder = builder.disable_untagged_union(); 71412a9d9c8Sopenharmony_ci } 71512a9d9c8Sopenharmony_ci 71612a9d9c8Sopenharmony_ci if disable_header_comment { 71712a9d9c8Sopenharmony_ci builder = builder.disable_header_comment(); 71812a9d9c8Sopenharmony_ci } 71912a9d9c8Sopenharmony_ci 72012a9d9c8Sopenharmony_ci if ignore_functions { 72112a9d9c8Sopenharmony_ci builder = builder.ignore_functions(); 72212a9d9c8Sopenharmony_ci } 72312a9d9c8Sopenharmony_ci 72412a9d9c8Sopenharmony_ci if ignore_methods { 72512a9d9c8Sopenharmony_ci builder = builder.ignore_methods(); 72612a9d9c8Sopenharmony_ci } 72712a9d9c8Sopenharmony_ci 72812a9d9c8Sopenharmony_ci if no_convert_floats { 72912a9d9c8Sopenharmony_ci builder = builder.no_convert_floats(); 73012a9d9c8Sopenharmony_ci } 73112a9d9c8Sopenharmony_ci 73212a9d9c8Sopenharmony_ci if no_doc_comments { 73312a9d9c8Sopenharmony_ci builder = builder.generate_comments(false); 73412a9d9c8Sopenharmony_ci } 73512a9d9c8Sopenharmony_ci 73612a9d9c8Sopenharmony_ci if no_recursive_allowlist { 73712a9d9c8Sopenharmony_ci builder = builder.allowlist_recursively(false); 73812a9d9c8Sopenharmony_ci } 73912a9d9c8Sopenharmony_ci 74012a9d9c8Sopenharmony_ci if objc_extern_crate { 74112a9d9c8Sopenharmony_ci builder = builder.objc_extern_crate(true); 74212a9d9c8Sopenharmony_ci } 74312a9d9c8Sopenharmony_ci 74412a9d9c8Sopenharmony_ci if generate_block { 74512a9d9c8Sopenharmony_ci builder = builder.generate_block(true); 74612a9d9c8Sopenharmony_ci } 74712a9d9c8Sopenharmony_ci 74812a9d9c8Sopenharmony_ci if block_extern_crate { 74912a9d9c8Sopenharmony_ci builder = builder.block_extern_crate(true); 75012a9d9c8Sopenharmony_ci } 75112a9d9c8Sopenharmony_ci 75212a9d9c8Sopenharmony_ci for ty in opaque_type { 75312a9d9c8Sopenharmony_ci builder = builder.opaque_type(ty); 75412a9d9c8Sopenharmony_ci } 75512a9d9c8Sopenharmony_ci 75612a9d9c8Sopenharmony_ci for line in raw_line { 75712a9d9c8Sopenharmony_ci builder = builder.raw_line(line); 75812a9d9c8Sopenharmony_ci } 75912a9d9c8Sopenharmony_ci 76012a9d9c8Sopenharmony_ci let mut values = module_raw_line.into_iter(); 76112a9d9c8Sopenharmony_ci while let Some(module) = values.next() { 76212a9d9c8Sopenharmony_ci let line = values.next().unwrap(); 76312a9d9c8Sopenharmony_ci builder = builder.module_raw_line(module, line); 76412a9d9c8Sopenharmony_ci } 76512a9d9c8Sopenharmony_ci 76612a9d9c8Sopenharmony_ci if use_core { 76712a9d9c8Sopenharmony_ci builder = builder.use_core(); 76812a9d9c8Sopenharmony_ci } 76912a9d9c8Sopenharmony_ci 77012a9d9c8Sopenharmony_ci if distrust_clang_mangling { 77112a9d9c8Sopenharmony_ci builder = builder.trust_clang_mangling(false); 77212a9d9c8Sopenharmony_ci } 77312a9d9c8Sopenharmony_ci 77412a9d9c8Sopenharmony_ci if conservative_inline_namespaces { 77512a9d9c8Sopenharmony_ci builder = builder.conservative_inline_namespaces(); 77612a9d9c8Sopenharmony_ci } 77712a9d9c8Sopenharmony_ci 77812a9d9c8Sopenharmony_ci if generate_inline_functions { 77912a9d9c8Sopenharmony_ci builder = builder.generate_inline_functions(true); 78012a9d9c8Sopenharmony_ci } 78112a9d9c8Sopenharmony_ci 78212a9d9c8Sopenharmony_ci for regex in allowlist_function { 78312a9d9c8Sopenharmony_ci builder = builder.allowlist_function(regex); 78412a9d9c8Sopenharmony_ci } 78512a9d9c8Sopenharmony_ci 78612a9d9c8Sopenharmony_ci for regex in allowlist_type { 78712a9d9c8Sopenharmony_ci builder = builder.allowlist_type(regex); 78812a9d9c8Sopenharmony_ci } 78912a9d9c8Sopenharmony_ci 79012a9d9c8Sopenharmony_ci for regex in allowlist_var { 79112a9d9c8Sopenharmony_ci builder = builder.allowlist_var(regex); 79212a9d9c8Sopenharmony_ci } 79312a9d9c8Sopenharmony_ci 79412a9d9c8Sopenharmony_ci for file in allowlist_file { 79512a9d9c8Sopenharmony_ci builder = builder.allowlist_file(file); 79612a9d9c8Sopenharmony_ci } 79712a9d9c8Sopenharmony_ci 79812a9d9c8Sopenharmony_ci for arg in clang_args { 79912a9d9c8Sopenharmony_ci builder = builder.clang_arg(arg); 80012a9d9c8Sopenharmony_ci } 80112a9d9c8Sopenharmony_ci 80212a9d9c8Sopenharmony_ci let output = if let Some(path) = &output { 80312a9d9c8Sopenharmony_ci let file = File::create(path)?; 80412a9d9c8Sopenharmony_ci if let Some(depfile) = depfile { 80512a9d9c8Sopenharmony_ci builder = builder.depfile(path, depfile); 80612a9d9c8Sopenharmony_ci } 80712a9d9c8Sopenharmony_ci Box::new(io::BufWriter::new(file)) as Box<dyn io::Write> 80812a9d9c8Sopenharmony_ci } else { 80912a9d9c8Sopenharmony_ci if let Some(depfile) = depfile { 81012a9d9c8Sopenharmony_ci builder = builder.depfile("-", depfile); 81112a9d9c8Sopenharmony_ci } 81212a9d9c8Sopenharmony_ci Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write> 81312a9d9c8Sopenharmony_ci }; 81412a9d9c8Sopenharmony_ci 81512a9d9c8Sopenharmony_ci if dump_preprocessed_input { 81612a9d9c8Sopenharmony_ci builder.dump_preprocessed_input()?; 81712a9d9c8Sopenharmony_ci } 81812a9d9c8Sopenharmony_ci 81912a9d9c8Sopenharmony_ci if no_record_matches { 82012a9d9c8Sopenharmony_ci builder = builder.record_matches(false); 82112a9d9c8Sopenharmony_ci } 82212a9d9c8Sopenharmony_ci 82312a9d9c8Sopenharmony_ci if no_size_t_is_usize { 82412a9d9c8Sopenharmony_ci builder = builder.size_t_is_usize(false); 82512a9d9c8Sopenharmony_ci } 82612a9d9c8Sopenharmony_ci 82712a9d9c8Sopenharmony_ci if no_rustfmt_bindings { 82812a9d9c8Sopenharmony_ci builder = builder.rustfmt_bindings(false); 82912a9d9c8Sopenharmony_ci } 83012a9d9c8Sopenharmony_ci 83112a9d9c8Sopenharmony_ci if let Some(path_str) = rustfmt_configuration_file { 83212a9d9c8Sopenharmony_ci let path = PathBuf::from(path_str); 83312a9d9c8Sopenharmony_ci 83412a9d9c8Sopenharmony_ci if no_rustfmt_bindings { 83512a9d9c8Sopenharmony_ci return Err(Error::new( 83612a9d9c8Sopenharmony_ci ErrorKind::Other, 83712a9d9c8Sopenharmony_ci "Cannot supply both --rustfmt-configuration-file and --no-rustfmt-bindings", 83812a9d9c8Sopenharmony_ci )); 83912a9d9c8Sopenharmony_ci } 84012a9d9c8Sopenharmony_ci 84112a9d9c8Sopenharmony_ci if !path.is_absolute() { 84212a9d9c8Sopenharmony_ci return Err(Error::new( 84312a9d9c8Sopenharmony_ci ErrorKind::Other, 84412a9d9c8Sopenharmony_ci "--rustfmt-configuration--file needs to be an absolute path!", 84512a9d9c8Sopenharmony_ci )); 84612a9d9c8Sopenharmony_ci } 84712a9d9c8Sopenharmony_ci 84812a9d9c8Sopenharmony_ci if path.to_str().is_none() { 84912a9d9c8Sopenharmony_ci return Err(Error::new( 85012a9d9c8Sopenharmony_ci ErrorKind::Other, 85112a9d9c8Sopenharmony_ci "--rustfmt-configuration-file contains non-valid UTF8 characters.", 85212a9d9c8Sopenharmony_ci )); 85312a9d9c8Sopenharmony_ci } 85412a9d9c8Sopenharmony_ci 85512a9d9c8Sopenharmony_ci builder = builder.rustfmt_configuration_file(Some(path)); 85612a9d9c8Sopenharmony_ci } 85712a9d9c8Sopenharmony_ci 85812a9d9c8Sopenharmony_ci for regex in no_partialeq { 85912a9d9c8Sopenharmony_ci builder = builder.no_partialeq(regex); 86012a9d9c8Sopenharmony_ci } 86112a9d9c8Sopenharmony_ci 86212a9d9c8Sopenharmony_ci for regex in no_copy { 86312a9d9c8Sopenharmony_ci builder = builder.no_copy(regex); 86412a9d9c8Sopenharmony_ci } 86512a9d9c8Sopenharmony_ci 86612a9d9c8Sopenharmony_ci for regex in no_debug { 86712a9d9c8Sopenharmony_ci builder = builder.no_debug(regex); 86812a9d9c8Sopenharmony_ci } 86912a9d9c8Sopenharmony_ci 87012a9d9c8Sopenharmony_ci for regex in no_default { 87112a9d9c8Sopenharmony_ci builder = builder.no_default(regex); 87212a9d9c8Sopenharmony_ci } 87312a9d9c8Sopenharmony_ci 87412a9d9c8Sopenharmony_ci for regex in no_hash { 87512a9d9c8Sopenharmony_ci builder = builder.no_hash(regex); 87612a9d9c8Sopenharmony_ci } 87712a9d9c8Sopenharmony_ci 87812a9d9c8Sopenharmony_ci for regex in must_use_type { 87912a9d9c8Sopenharmony_ci builder = builder.must_use_type(regex); 88012a9d9c8Sopenharmony_ci } 88112a9d9c8Sopenharmony_ci 88212a9d9c8Sopenharmony_ci if let Some(dynamic_library_name) = dynamic_loading { 88312a9d9c8Sopenharmony_ci builder = builder.dynamic_library_name(dynamic_library_name); 88412a9d9c8Sopenharmony_ci } 88512a9d9c8Sopenharmony_ci 88612a9d9c8Sopenharmony_ci if dynamic_link_require_all { 88712a9d9c8Sopenharmony_ci builder = builder.dynamic_link_require_all(true); 88812a9d9c8Sopenharmony_ci } 88912a9d9c8Sopenharmony_ci 89012a9d9c8Sopenharmony_ci if respect_cxx_access_specs { 89112a9d9c8Sopenharmony_ci builder = builder.respect_cxx_access_specs(true); 89212a9d9c8Sopenharmony_ci } 89312a9d9c8Sopenharmony_ci 89412a9d9c8Sopenharmony_ci if translate_enum_integer_types { 89512a9d9c8Sopenharmony_ci builder = builder.translate_enum_integer_types(true); 89612a9d9c8Sopenharmony_ci } 89712a9d9c8Sopenharmony_ci 89812a9d9c8Sopenharmony_ci if c_naming { 89912a9d9c8Sopenharmony_ci builder = builder.c_naming(true); 90012a9d9c8Sopenharmony_ci } 90112a9d9c8Sopenharmony_ci 90212a9d9c8Sopenharmony_ci if explicit_padding { 90312a9d9c8Sopenharmony_ci builder = builder.explicit_padding(true); 90412a9d9c8Sopenharmony_ci } 90512a9d9c8Sopenharmony_ci 90612a9d9c8Sopenharmony_ci if vtable_generation { 90712a9d9c8Sopenharmony_ci builder = builder.vtable_generation(true); 90812a9d9c8Sopenharmony_ci } 90912a9d9c8Sopenharmony_ci 91012a9d9c8Sopenharmony_ci if sort_semantically { 91112a9d9c8Sopenharmony_ci builder = builder.sort_semantically(true); 91212a9d9c8Sopenharmony_ci } 91312a9d9c8Sopenharmony_ci 91412a9d9c8Sopenharmony_ci if merge_extern_blocks { 91512a9d9c8Sopenharmony_ci builder = builder.merge_extern_blocks(true); 91612a9d9c8Sopenharmony_ci } 91712a9d9c8Sopenharmony_ci 91812a9d9c8Sopenharmony_ci for abi_override in override_abi { 91912a9d9c8Sopenharmony_ci let (regex, abi_str) = abi_override 92012a9d9c8Sopenharmony_ci .rsplit_once('=') 92112a9d9c8Sopenharmony_ci .expect("Invalid ABI override: Missing `=`"); 92212a9d9c8Sopenharmony_ci let abi = abi_str 92312a9d9c8Sopenharmony_ci .parse() 92412a9d9c8Sopenharmony_ci .unwrap_or_else(|err| panic!("Invalid ABI override: {}", err)); 92512a9d9c8Sopenharmony_ci builder = builder.override_abi(abi, regex); 92612a9d9c8Sopenharmony_ci } 92712a9d9c8Sopenharmony_ci 92812a9d9c8Sopenharmony_ci if wrap_unsafe_ops { 92912a9d9c8Sopenharmony_ci builder = builder.wrap_unsafe_ops(true); 93012a9d9c8Sopenharmony_ci } 93112a9d9c8Sopenharmony_ci 93212a9d9c8Sopenharmony_ci #[derive(Debug)] 93312a9d9c8Sopenharmony_ci struct CustomDeriveCallback { 93412a9d9c8Sopenharmony_ci derives: Vec<String>, 93512a9d9c8Sopenharmony_ci kind: Option<TypeKind>, 93612a9d9c8Sopenharmony_ci regex_set: bindgen::RegexSet, 93712a9d9c8Sopenharmony_ci } 93812a9d9c8Sopenharmony_ci 93912a9d9c8Sopenharmony_ci impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback { 94012a9d9c8Sopenharmony_ci fn cli_args(&self) -> Vec<String> { 94112a9d9c8Sopenharmony_ci let mut args = vec![]; 94212a9d9c8Sopenharmony_ci 94312a9d9c8Sopenharmony_ci let flag = match &self.kind { 94412a9d9c8Sopenharmony_ci None => "--with-derive-custom", 94512a9d9c8Sopenharmony_ci Some(TypeKind::Struct) => "--with-derive-custom-struct", 94612a9d9c8Sopenharmony_ci Some(TypeKind::Enum) => "--with-derive-custom-enum", 94712a9d9c8Sopenharmony_ci Some(TypeKind::Union) => "--with-derive-custom-union", 94812a9d9c8Sopenharmony_ci }; 94912a9d9c8Sopenharmony_ci 95012a9d9c8Sopenharmony_ci let derives = self.derives.join(","); 95112a9d9c8Sopenharmony_ci 95212a9d9c8Sopenharmony_ci for item in self.regex_set.get_items() { 95312a9d9c8Sopenharmony_ci args.extend_from_slice(&[ 95412a9d9c8Sopenharmony_ci flag.to_owned(), 95512a9d9c8Sopenharmony_ci format!("{}={}", item, derives), 95612a9d9c8Sopenharmony_ci ]); 95712a9d9c8Sopenharmony_ci } 95812a9d9c8Sopenharmony_ci 95912a9d9c8Sopenharmony_ci args 96012a9d9c8Sopenharmony_ci } 96112a9d9c8Sopenharmony_ci 96212a9d9c8Sopenharmony_ci fn add_derives( 96312a9d9c8Sopenharmony_ci &self, 96412a9d9c8Sopenharmony_ci info: &bindgen::callbacks::DeriveInfo<'_>, 96512a9d9c8Sopenharmony_ci ) -> Vec<String> { 96612a9d9c8Sopenharmony_ci if self.kind.map(|kind| kind == info.kind).unwrap_or(true) && 96712a9d9c8Sopenharmony_ci self.regex_set.matches(info.name) 96812a9d9c8Sopenharmony_ci { 96912a9d9c8Sopenharmony_ci return self.derives.clone(); 97012a9d9c8Sopenharmony_ci } 97112a9d9c8Sopenharmony_ci vec![] 97212a9d9c8Sopenharmony_ci } 97312a9d9c8Sopenharmony_ci } 97412a9d9c8Sopenharmony_ci 97512a9d9c8Sopenharmony_ci for (custom_derives, kind) in [ 97612a9d9c8Sopenharmony_ci (with_derive_custom, None), 97712a9d9c8Sopenharmony_ci (with_derive_custom_struct, Some(TypeKind::Struct)), 97812a9d9c8Sopenharmony_ci (with_derive_custom_enum, Some(TypeKind::Enum)), 97912a9d9c8Sopenharmony_ci (with_derive_custom_union, Some(TypeKind::Union)), 98012a9d9c8Sopenharmony_ci ] { 98112a9d9c8Sopenharmony_ci for custom_derive in custom_derives { 98212a9d9c8Sopenharmony_ci let (regex, derives) = custom_derive 98312a9d9c8Sopenharmony_ci .rsplit_once('=') 98412a9d9c8Sopenharmony_ci .expect("Invalid custom derive argument: Missing `=`"); 98512a9d9c8Sopenharmony_ci let derives = derives.split(',').map(|s| s.to_owned()).collect(); 98612a9d9c8Sopenharmony_ci 98712a9d9c8Sopenharmony_ci let mut regex_set = RegexSet::new(); 98812a9d9c8Sopenharmony_ci regex_set.insert(regex); 98912a9d9c8Sopenharmony_ci regex_set.build(false); 99012a9d9c8Sopenharmony_ci 99112a9d9c8Sopenharmony_ci builder = builder.parse_callbacks(Box::new(CustomDeriveCallback { 99212a9d9c8Sopenharmony_ci derives, 99312a9d9c8Sopenharmony_ci kind, 99412a9d9c8Sopenharmony_ci regex_set, 99512a9d9c8Sopenharmony_ci })); 99612a9d9c8Sopenharmony_ci } 99712a9d9c8Sopenharmony_ci } 99812a9d9c8Sopenharmony_ci 99912a9d9c8Sopenharmony_ci if wrap_static_fns { 100012a9d9c8Sopenharmony_ci builder = builder.wrap_static_fns(true); 100112a9d9c8Sopenharmony_ci } 100212a9d9c8Sopenharmony_ci 100312a9d9c8Sopenharmony_ci if let Some(path) = wrap_static_fns_path { 100412a9d9c8Sopenharmony_ci builder = builder.wrap_static_fns_path(path); 100512a9d9c8Sopenharmony_ci } 100612a9d9c8Sopenharmony_ci 100712a9d9c8Sopenharmony_ci if let Some(suffix) = wrap_static_fns_suffix { 100812a9d9c8Sopenharmony_ci builder = builder.wrap_static_fns_suffix(suffix); 100912a9d9c8Sopenharmony_ci } 101012a9d9c8Sopenharmony_ci 101112a9d9c8Sopenharmony_ci Ok((builder, output, verbose)) 101212a9d9c8Sopenharmony_ci} 1013