//! Generate Rust bindings for C and C++ libraries.
//!
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
//! functions and use types defined in the header.
//!
//! See the [`Builder`](./struct.Builder.html) struct for usage.
//!
//! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for
//! additional documentation.
#![deny(missing_docs)]
#![deny(unused_extern_crates)]
// To avoid rather annoying warnings when matching with CXCursor_xxx as a
// constant.
#![allow(non_upper_case_globals)]
// `quote!` nests quite deeply.
#![recursion_limit = "128"]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate quote;

#[cfg(feature = "logging")]
#[macro_use]
extern crate log;

#[cfg(not(feature = "logging"))]
#[macro_use]
mod log_stubs;

#[macro_use]
mod extra_assertions;

// A macro to declare an internal module for which we *must* provide
// documentation for. If we are building with the "testing_only_docs" feature,
// then the module is declared public, and our `#![deny(missing_docs)]` pragma
// applies to it. This feature is used in CI, so we won't let anything slip by
// undocumented. Normal builds, however, will leave the module private, so that
// we don't expose internals to library consumers.
macro_rules! doc_mod {
    ($m:ident, $doc_mod_name:ident) => {
        #[cfg(feature = "testing_only_docs")]
        pub mod $doc_mod_name {
            //! Autogenerated documentation module.
            pub use super::$m::*;
        }
    };
}

mod clang;
mod codegen;
mod features;
mod ir;
mod parse;
mod regex_set;
mod time;

pub mod callbacks;

doc_mod!(clang, clang_docs);
doc_mod!(features, features_docs);
doc_mod!(ir, ir_docs);
doc_mod!(parse, parse_docs);
doc_mod!(regex_set, regex_set_docs);

pub use crate::codegen::{AliasVariation, EnumVariation, MacroTypeVariation};
use crate::features::RustFeatures;
pub use crate::features::{
    RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS,
};
use crate::ir::context::{BindgenContext, ItemId};
use crate::ir::item::Item;
use crate::parse::{ClangItemParser, ParseError};
use crate::regex_set::RegexSet;

use std::borrow::Cow;
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::{env, iter};

// Some convenient typedefs for a fast hash map and hash set.
type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;
type HashSet<K> = ::rustc_hash::FxHashSet<K>;
pub(crate) use std::collections::hash_map::Entry;

/// Default prefix for the anon fields.
pub const DEFAULT_ANON_FIELDS_PREFIX: &'static str = "__bindgen_anon_";

fn file_is_cpp(name_file: &str) -> bool {
    name_file.ends_with(".hpp") ||
        name_file.ends_with(".hxx") ||
        name_file.ends_with(".hh") ||
        name_file.ends_with(".h++")
}

fn args_are_cpp(clang_args: &[String]) -> bool {
    for w in clang_args.windows(2) {
        if w[0] == "-xc++" || w[1] == "-xc++" {
            return true;
        }
        if w[0] == "-x" && w[1] == "c++" {
            return true;
        }
        if w[0] == "-include" && file_is_cpp(&w[1]) {
            return true;
        }
    }
    false
}

bitflags! {
    /// A type used to indicate which kind of items we have to generate.
    pub struct CodegenConfig: u32 {
        /// Whether to generate functions.
        const FUNCTIONS = 1 << 0;
        /// Whether to generate types.
        const TYPES = 1 << 1;
        /// Whether to generate constants.
        const VARS = 1 << 2;
        /// Whether to generate methods.
        const METHODS = 1 << 3;
        /// Whether to generate constructors
        const CONSTRUCTORS = 1 << 4;
        /// Whether to generate destructors.
        const DESTRUCTORS = 1 << 5;
    }
}

impl CodegenConfig {
    /// Returns true if functions should be generated.
    pub fn functions(self) -> bool {
        self.contains(CodegenConfig::FUNCTIONS)
    }

    /// Returns true if types should be generated.
    pub fn types(self) -> bool {
        self.contains(CodegenConfig::TYPES)
    }

    /// Returns true if constants should be generated.
    pub fn vars(self) -> bool {
        self.contains(CodegenConfig::VARS)
    }

    /// Returns true if methds should be generated.
    pub fn methods(self) -> bool {
        self.contains(CodegenConfig::METHODS)
    }

    /// Returns true if constructors should be generated.
    pub fn constructors(self) -> bool {
        self.contains(CodegenConfig::CONSTRUCTORS)
    }

    /// Returns true if destructors should be generated.
    pub fn destructors(self) -> bool {
        self.contains(CodegenConfig::DESTRUCTORS)
    }
}

impl Default for CodegenConfig {
    fn default() -> Self {
        CodegenConfig::all()
    }
}

/// Configure and generate Rust bindings for a C/C++ header.
///
/// This is the main entry point to the library.
///
/// ```ignore
/// use bindgen::builder;
///
/// // Configure and generate bindings.
/// let bindings = builder().header("path/to/input/header")
///     .allowlist_type("SomeCoolClass")
///     .allowlist_function("do_some_cool_thing")
///     .generate()?;
///
/// // Write the generated bindings to an output file.
/// bindings.write_to_file("path/to/output.rs")?;
/// ```
///
/// # Enums
///
/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
/// the pattern passed to several methods:
///
/// 1. [`constified_enum_module()`](#method.constified_enum_module)
/// 2. [`bitfield_enum()`](#method.bitfield_enum)
/// 3. [`newtype_enum()`](#method.newtype_enum)
/// 4. [`rustified_enum()`](#method.rustified_enum)
///
/// For each C enum, bindgen tries to match the pattern in the following order:
///
/// 1. Constified enum module
/// 2. Bitfield enum
/// 3. Newtype enum
/// 4. Rustified enum
///
/// If none of the above patterns match, then bindgen will generate a set of Rust constants.
///
/// # Clang arguments
///
/// Extra arguments can be passed to with clang:
/// 1. [`clang_arg()`](#method.clang_arg): takes a single argument
/// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments
/// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate
///    environment variable of arguments
///
/// Clang arguments specific to your crate should be added via the
/// `clang_arg()`/`clang_args()` methods.
///
/// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to
/// add additional arguments. For example, to build against a different sysroot a user could set
/// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`.
#[derive(Debug, Default)]
pub struct Builder {
    options: BindgenOptions,
    input_headers: Vec<String>,
    // Tuples of unsaved file contents of the form (name, contents).
    input_header_contents: Vec<(String, String)>,
}

/// Construct a new [`Builder`](./struct.Builder.html).
pub fn builder() -> Builder {
    Default::default()
}

impl Builder {
    /// Generates the command line flags use for creating `Builder`.
    pub fn command_line_flags(&self) -> Vec<String> {
        let mut output_vector: Vec<String> = Vec::new();

        if let Some(header) = self.input_headers.last().cloned() {
            // Positional argument 'header'
            output_vector.push(header);
        }

        output_vector.push("--rust-target".into());
        output_vector.push(self.options.rust_target.into());

        // FIXME(emilio): This is a bit hacky, maybe we should stop re-using the
        // RustFeatures to store the "disable_untagged_union" call, and make it
        // a different flag that we check elsewhere / in generate().
        if !self.options.rust_features.untagged_union &&
            RustFeatures::from(self.options.rust_target).untagged_union
        {
            output_vector.push("--disable-untagged-union".into());
        }

        if self.options.default_enum_style != Default::default() {
            output_vector.push("--default-enum-style".into());
            output_vector.push(
                match self.options.default_enum_style {
                    codegen::EnumVariation::Rust {
                        non_exhaustive: false,
                    } => "rust",
                    codegen::EnumVariation::Rust {
                        non_exhaustive: true,
                    } => "rust_non_exhaustive",
                    codegen::EnumVariation::NewType { is_bitfield: true } => {
                        "bitfield"
                    }
                    codegen::EnumVariation::NewType { is_bitfield: false } => {
                        "newtype"
                    }
                    codegen::EnumVariation::Consts => "consts",
                    codegen::EnumVariation::ModuleConsts => "moduleconsts",
                }
                .into(),
            )
        }

        if self.options.default_macro_constant_type != Default::default() {
            output_vector.push("--default-macro-constant-type".into());
            output_vector
                .push(self.options.default_macro_constant_type.as_str().into());
        }

        if self.options.default_alias_style != Default::default() {
            output_vector.push("--default-alias-style".into());
            output_vector
                .push(self.options.default_alias_style.as_str().into());
        }

        let regex_sets = &[
            (&self.options.bitfield_enums, "--bitfield-enum"),
            (&self.options.newtype_enums, "--newtype-enum"),
            (&self.options.rustified_enums, "--rustified-enum"),
            (
                &self.options.rustified_non_exhaustive_enums,
                "--rustified-enum-non-exhaustive",
            ),
            (
                &self.options.constified_enum_modules,
                "--constified-enum-module",
            ),
            (&self.options.constified_enums, "--constified-enum"),
            (&self.options.type_alias, "--type-alias"),
            (&self.options.new_type_alias, "--new-type-alias"),
            (&self.options.new_type_alias_deref, "--new-type-alias-deref"),
            (&self.options.blocklisted_types, "--blocklist-type"),
            (&self.options.blocklisted_functions, "--blocklist-function"),
            (&self.options.blocklisted_items, "--blocklist-item"),
            (&self.options.opaque_types, "--opaque-type"),
            (&self.options.allowlisted_functions, "--allowlist-function"),
            (&self.options.allowlisted_types, "--allowlist-type"),
            (&self.options.allowlisted_vars, "--allowlist-var"),
            (&self.options.no_partialeq_types, "--no-partialeq"),
            (&self.options.no_copy_types, "--no-copy"),
            (&self.options.no_debug_types, "--no-debug"),
            (&self.options.no_default_types, "--no-default"),
            (&self.options.no_hash_types, "--no-hash"),
        ];

        for (set, flag) in regex_sets {
            for item in set.get_items() {
                output_vector.push((*flag).to_owned());
                output_vector.push(item.to_owned());
            }
        }

        if !self.options.layout_tests {
            output_vector.push("--no-layout-tests".into());
        }

        if self.options.impl_debug {
            output_vector.push("--impl-debug".into());
        }

        if self.options.impl_partialeq {
            output_vector.push("--impl-partialeq".into());
        }

        if !self.options.derive_copy {
            output_vector.push("--no-derive-copy".into());
        }

        if !self.options.derive_debug {
            output_vector.push("--no-derive-debug".into());
        }

        if !self.options.derive_default {
            output_vector.push("--no-derive-default".into());
        } else {
            output_vector.push("--with-derive-default".into());
        }

        if self.options.derive_hash {
            output_vector.push("--with-derive-hash".into());
        }

        if self.options.derive_partialord {
            output_vector.push("--with-derive-partialord".into());
        }

        if self.options.derive_ord {
            output_vector.push("--with-derive-ord".into());
        }

        if self.options.derive_partialeq {
            output_vector.push("--with-derive-partialeq".into());
        }

        if self.options.derive_eq {
            output_vector.push("--with-derive-eq".into());
        }

        if self.options.time_phases {
            output_vector.push("--time-phases".into());
        }

        if !self.options.generate_comments {
            output_vector.push("--no-doc-comments".into());
        }

        if !self.options.allowlist_recursively {
            output_vector.push("--no-recursive-allowlist".into());
        }

        if self.options.objc_extern_crate {
            output_vector.push("--objc-extern-crate".into());
        }

        if self.options.generate_block {
            output_vector.push("--generate-block".into());
        }

        if self.options.block_extern_crate {
            output_vector.push("--block-extern-crate".into());
        }

        if self.options.builtins {
            output_vector.push("--builtins".into());
        }

        if let Some(ref prefix) = self.options.ctypes_prefix {
            output_vector.push("--ctypes-prefix".into());
            output_vector.push(prefix.clone());
        }

        if self.options.anon_fields_prefix != DEFAULT_ANON_FIELDS_PREFIX {
            output_vector.push("--anon-fields-prefix".into());
            output_vector.push(self.options.anon_fields_prefix.clone());
        }

        if self.options.emit_ast {
            output_vector.push("--emit-clang-ast".into());
        }

        if self.options.emit_ir {
            output_vector.push("--emit-ir".into());
        }
        if let Some(ref graph) = self.options.emit_ir_graphviz {
            output_vector.push("--emit-ir-graphviz".into());
            output_vector.push(graph.clone())
        }
        if self.options.enable_cxx_namespaces {
            output_vector.push("--enable-cxx-namespaces".into());
        }
        if self.options.enable_function_attribute_detection {
            output_vector.push("--enable-function-attribute-detection".into());
        }
        if self.options.disable_name_namespacing {
            output_vector.push("--disable-name-namespacing".into());
        }
        if self.options.disable_nested_struct_naming {
            output_vector.push("--disable-nested-struct-naming".into());
        }

        if self.options.disable_header_comment {
            output_vector.push("--disable-header-comment".into());
        }

        if !self.options.codegen_config.functions() {
            output_vector.push("--ignore-functions".into());
        }

        output_vector.push("--generate".into());

        //Temporary placeholder for below 4 options
        let mut options: Vec<String> = Vec::new();
        if self.options.codegen_config.functions() {
            options.push("functions".into());
        }
        if self.options.codegen_config.types() {
            options.push("types".into());
        }
        if self.options.codegen_config.vars() {
            options.push("vars".into());
        }
        if self.options.codegen_config.methods() {
            options.push("methods".into());
        }
        if self.options.codegen_config.constructors() {
            options.push("constructors".into());
        }
        if self.options.codegen_config.destructors() {
            options.push("destructors".into());
        }

        output_vector.push(options.join(","));

        if !self.options.codegen_config.methods() {
            output_vector.push("--ignore-methods".into());
        }

        if !self.options.convert_floats {
            output_vector.push("--no-convert-floats".into());
        }

        if !self.options.prepend_enum_name {
            output_vector.push("--no-prepend-enum-name".into());
        }

        if self.options.fit_macro_constants {
            output_vector.push("--fit-macro-constant-types".into());
        }

        if self.options.array_pointers_in_arguments {
            output_vector.push("--use-array-pointers-in-arguments".into());
        }

        if let Some(ref wasm_import_module_name) =
            self.options.wasm_import_module_name
        {
            output_vector.push("--wasm-import-module-name".into());
            output_vector.push(wasm_import_module_name.clone());
        }

        for line in &self.options.raw_lines {
            output_vector.push("--raw-line".into());
            output_vector.push(line.clone());
        }

        for (module, lines) in &self.options.module_lines {
            for line in lines.iter() {
                output_vector.push("--module-raw-line".into());
                output_vector.push(module.clone());
                output_vector.push(line.clone());
            }
        }

        if self.options.use_core {
            output_vector.push("--use-core".into());
        }

        if self.options.conservative_inline_namespaces {
            output_vector.push("--conservative-inline-namespaces".into());
        }

        if self.options.generate_inline_functions {
            output_vector.push("--generate-inline-functions".into());
        }

        if !self.options.record_matches {
            output_vector.push("--no-record-matches".into());
        }

        if self.options.size_t_is_usize {
            output_vector.push("--size_t-is-usize".into());
        }

        if !self.options.rustfmt_bindings {
            output_vector.push("--no-rustfmt-bindings".into());
        }

        if let Some(path) = self
            .options
            .rustfmt_configuration_file
            .as_ref()
            .and_then(|f| f.to_str())
        {
            output_vector.push("--rustfmt-configuration-file".into());
            output_vector.push(path.into());
        }

        if let Some(ref name) = self.options.dynamic_library_name {
            output_vector.push("--dynamic-loading".into());
            output_vector.push(name.clone());
        }

        if self.options.dynamic_link_require_all {
            output_vector.push("--dynamic-link-require-all".into());
        }

        if self.options.respect_cxx_access_specs {
            output_vector.push("--respect-cxx-access-specs".into());
        }

        if self.options.translate_enum_integer_types {
            output_vector.push("--translate-enum-integer-types".into());
        }

        // Add clang arguments

        output_vector.push("--".into());

        if !self.options.clang_args.is_empty() {
            output_vector.extend(self.options.clang_args.iter().cloned());
        }

        if self.input_headers.len() > 1 {
            // To pass more than one header, we need to pass all but the last
            // header via the `-include` clang arg
            for header in &self.input_headers[..self.input_headers.len() - 1] {
                output_vector.push("-include".to_string());
                output_vector.push(header.clone());
            }
        }

        output_vector
    }

    /// Add an input C/C++ header to generate bindings for.
    ///
    /// This can be used to generate bindings to a single header:
    ///
    /// ```ignore
    /// let bindings = bindgen::Builder::default()
    ///     .header("input.h")
    ///     .generate()
    ///     .unwrap();
    /// ```
    ///
    /// Or you can invoke it multiple times to generate bindings to multiple
    /// headers:
    ///
    /// ```ignore
    /// let bindings = bindgen::Builder::default()
    ///     .header("first.h")
    ///     .header("second.h")
    ///     .header("third.h")
    ///     .generate()
    ///     .unwrap();
    /// ```
    pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
        self.input_headers.push(header.into());
        self
    }

    /// Add `contents` as an input C/C++ header named `name`.
    ///
    /// The file `name` will be added to the clang arguments.
    pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
        // Apparently clang relies on having virtual FS correspondent to
        // the real one, so we need absolute paths here
        let absolute_path = env::current_dir()
            .expect("Cannot retrieve current directory")
            .join(name)
            .to_str()
            .expect("Cannot convert current directory name to string")
            .to_owned();
        self.input_header_contents
            .push((absolute_path, contents.into()));
        self
    }

    /// Specify the rust target
    ///
    /// The default is the latest stable Rust version
    pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
        self.options.set_rust_target(rust_target);
        self
    }

    /// Disable support for native Rust unions, if supported.
    pub fn disable_untagged_union(mut self) -> Self {
        self.options.rust_features.untagged_union = false;
        self
    }

    /// Disable insertion of bindgen's version identifier into generated
    /// bindings.
    pub fn disable_header_comment(mut self) -> Self {
        self.options.disable_header_comment = true;
        self
    }

    /// Set the output graphviz file.
    pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
        let path = path.into();
        self.options.emit_ir_graphviz = Some(path);
        self
    }

    /// Whether the generated bindings should contain documentation comments
    /// (docstrings) or not. This is set to true by default.
    ///
    /// Note that clang by default excludes comments from system headers, pass
    /// `-fretain-comments-from-system-headers` as
    /// [`clang_arg`][Builder::clang_arg] to include them. It can also be told
    /// to process all comments (not just documentation ones) using the
    /// `-fparse-all-comments` flag. See [slides on clang comment parsing](
    /// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for
    /// background and examples.
    pub fn generate_comments(mut self, doit: bool) -> Self {
        self.options.generate_comments = doit;
        self
    }

    /// Whether to allowlist recursively or not. Defaults to true.
    ///
    /// Given that we have explicitly allowlisted the "initiate_dance_party"
    /// function in this C header:
    ///
    /// ```c
    /// typedef struct MoonBoots {
    ///     int bouncy_level;
    /// } MoonBoots;
    ///
    /// void initiate_dance_party(MoonBoots* boots);
    /// ```
    ///
    /// We would normally generate bindings to both the `initiate_dance_party`
    /// function and the `MoonBoots` struct that it transitively references. By
    /// configuring with `allowlist_recursively(false)`, `bindgen` will not emit
    /// bindings for anything except the explicitly allowlisted items, and there
    /// would be no emitted struct definition for `MoonBoots`. However, the
    /// `initiate_dance_party` function would still reference `MoonBoots`!
    ///
    /// **Disabling this feature will almost certainly cause `bindgen` to emit
    /// bindings that will not compile!** If you disable this feature, then it
    /// is *your* responsibility to provide definitions for every type that is
    /// referenced from an explicitly allowlisted item. One way to provide the
    /// definitions is by using the [`Builder::raw_line`](#method.raw_line)
    /// method, another would be to define them in Rust and then `include!(...)`
    /// the bindings immediately afterwards.
    pub fn allowlist_recursively(mut self, doit: bool) -> Self {
        self.options.allowlist_recursively = doit;
        self
    }

    /// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
    /// in the prologue of the files generated from objective-c files
    pub fn objc_extern_crate(mut self, doit: bool) -> Self {
        self.options.objc_extern_crate = doit;
        self
    }

    /// Generate proper block signatures instead of void pointers.
    pub fn generate_block(mut self, doit: bool) -> Self {
        self.options.generate_block = doit;
        self
    }

    /// Generate `#[macro_use] extern crate block;` instead of `use block;`
    /// in the prologue of the files generated from apple block files
    pub fn block_extern_crate(mut self, doit: bool) -> Self {
        self.options.block_extern_crate = doit;
        self
    }

    /// Whether to use the clang-provided name mangling. This is true by default
    /// and probably needed for C++ features.
    ///
    /// However, some old libclang versions seem to return incorrect results in
    /// some cases for non-mangled functions, see [1], so we allow disabling it.
    ///
    /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
    pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
        self.options.enable_mangling = doit;
        self
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "Use blocklist_type instead")]
    pub fn hide_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.blocklist_type(arg)
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "Use blocklist_type instead")]
    pub fn blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.blocklist_type(arg)
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    ///
    /// To blocklist types prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_types.insert(arg);
        self
    }

    /// Hide the given function from the generated bindings. Regular expressions
    /// are supported.
    #[deprecated(note = "Use blocklist_function instead")]
    pub fn blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder {
        self.blocklist_function(arg)
    }

    /// Hide the given function from the generated bindings. Regular expressions
    /// are supported.
    ///
    /// To blocklist functions prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_functions.insert(arg);
        self
    }

    /// Hide the given item from the generated bindings, regardless of
    /// whether it's a type, function, module, etc. Regular
    /// expressions are supported.
    #[deprecated(note = "Use blocklist_item instead")]
    pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_items.insert(arg);
        self
    }

    /// Hide the given item from the generated bindings, regardless of
    /// whether it's a type, function, module, etc. Regular
    /// expressions are supported.
    ///
    /// To blocklist items prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_items.insert(arg);
        self
    }

    /// Treat the given type as opaque in the generated bindings. Regular
    /// expressions are supported.
    ///
    /// To change types prefixed with "mylib" into opaque, use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.opaque_types.insert(arg);
        self
    }

    /// Allowlist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "use allowlist_type instead")]
    pub fn whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_type(arg)
    }

    /// Allowlist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "use allowlist_type instead")]
    pub fn whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_type(arg)
    }

    /// Allowlist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    ///
    /// To allowlist types prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.allowlisted_types.insert(arg);
        self
    }

    /// Allowlist the given function so that it (and all types that it
    /// transitively refers to) appears in the generated bindings. Regular
    /// expressions are supported.
    ///
    /// To allowlist functions prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.allowlisted_functions.insert(arg);
        self
    }

    /// Allowlist the given function.
    ///
    /// Deprecated: use allowlist_function instead.
    #[deprecated(note = "use allowlist_function instead")]
    pub fn whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_function(arg)
    }

    /// Allowlist the given function.
    ///
    /// Deprecated: use allowlist_function instead.
    #[deprecated(note = "use allowlist_function instead")]
    pub fn whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_function(arg)
    }

    /// Allowlist the given variable so that it (and all types that it
    /// transitively refers to) appears in the generated bindings. Regular
    /// expressions are supported.
    ///
    /// To allowlist variables prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.allowlisted_vars.insert(arg);
        self
    }

    /// Deprecated: use allowlist_var instead.
    #[deprecated(note = "use allowlist_var instead")]
    pub fn whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_var(arg)
    }

    /// Allowlist the given variable.
    ///
    /// Deprecated: use allowlist_var instead.
    #[deprecated(note = "use allowlist_var instead")]
    pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_var(arg)
    }

    /// Set the default style of code to generate for enums
    pub fn default_enum_style(
        mut self,
        arg: codegen::EnumVariation,
    ) -> Builder {
        self.options.default_enum_style = arg;
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as being
    /// bitfield-like. Regular expressions are supported.
    ///
    /// This makes bindgen generate a type that isn't a rust `enum`. Regular
    /// expressions are supported.
    ///
    /// This is similar to the newtype enum style, but with the bitwise
    /// operators implemented.
    pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.bitfield_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a newtype.
    /// Regular expressions are supported.
    ///
    /// This makes bindgen generate a type that isn't a Rust `enum`. Regular
    /// expressions are supported.
    pub fn newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.newtype_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a Rust
    /// enum.
    ///
    /// This makes bindgen generate enums instead of constants. Regular
    /// expressions are supported.
    ///
    /// **Use this with caution**, creating this in unsafe code
    /// (including FFI) with an invalid value will invoke undefined behaviour.
    /// You may want to use the newtype enum style instead.
    pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.rustified_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a Rust
    /// enum with the `#[non_exhaustive]` attribute.
    ///
    /// This makes bindgen generate enums instead of constants. Regular
    /// expressions are supported.
    ///
    /// **Use this with caution**, creating this in unsafe code
    /// (including FFI) with an invalid value will invoke undefined behaviour.
    /// You may want to use the newtype enum style instead.
    pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(
        mut self,
        arg: T,
    ) -> Builder {
        self.options.rustified_non_exhaustive_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a set of
    /// constants that are not to be put into a module.
    pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.constified_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a set of
    /// constants that should be put into a module.
    ///
    /// This makes bindgen generate modules containing constants instead of
    /// just constants. Regular expressions are supported.
    pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.constified_enum_modules.insert(arg);
        self
    }

    /// Set the default type for macro constants
    pub fn default_macro_constant_type(
        mut self,
        arg: codegen::MacroTypeVariation,
    ) -> Builder {
        self.options.default_macro_constant_type = arg;
        self
    }

    /// Set the default style of code to generate for typedefs
    pub fn default_alias_style(
        mut self,
        arg: codegen::AliasVariation,
    ) -> Builder {
        self.options.default_alias_style = arg;
        self
    }

    /// Mark the given typedef alias (or set of aliases, if using a pattern) to
    /// use regular Rust type aliasing.
    ///
    /// This is the default behavior and should be used if `default_alias_style`
    /// was set to NewType or NewTypeDeref and you want to override it for a
    /// set of typedefs.
    pub fn type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.type_alias.insert(arg);
        self
    }

    /// Mark the given typedef alias (or set of aliases, if using a pattern) to
    /// be generated as a new type by having the aliased type be wrapped in a
    /// #[repr(transparent)] struct.
    ///
    /// Used to enforce stricter type checking.
    pub fn new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.new_type_alias.insert(arg);
        self
    }

    /// Mark the given typedef alias (or set of aliases, if using a pattern) to
    /// be generated as a new type by having the aliased type be wrapped in a
    /// #[repr(transparent)] struct and also have an automatically generated
    /// impl's of `Deref` and `DerefMut` to their aliased type.
    pub fn new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.new_type_alias_deref.insert(arg);
        self
    }

    /// Add a string to prepend to the generated bindings. The string is passed
    /// through without any modification.
    pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.raw_lines.push(arg.into());
        self
    }

    /// Add a given line to the beginning of module `mod`.
    pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
    where
        T: Into<String>,
        U: Into<String>,
    {
        self.options
            .module_lines
            .entry(mod_.into())
            .or_insert_with(Vec::new)
            .push(line.into());
        self
    }

    /// Add a given set of lines to the beginning of module `mod`.
    pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
    where
        T: Into<String>,
        I: IntoIterator,
        I::Item: Into<String>,
    {
        self.options
            .module_lines
            .entry(mod_.into())
            .or_insert_with(Vec::new)
            .extend(lines.into_iter().map(Into::into));
        self
    }

    /// Add an argument to be passed straight through to clang.
    pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.clang_args.push(arg.into());
        self
    }

    /// Add arguments to be passed straight through to clang.
    pub fn clang_args<I>(mut self, iter: I) -> Builder
    where
        I: IntoIterator,
        I::Item: AsRef<str>,
    {
        for arg in iter {
            self = self.clang_arg(arg.as_ref())
        }
        self
    }

    /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
    /// in the generated Rust.
    pub fn emit_builtins(mut self) -> Builder {
        self.options.builtins = true;
        self
    }

    /// Avoid converting floats to `f32`/`f64` by default.
    pub fn no_convert_floats(mut self) -> Self {
        self.options.convert_floats = false;
        self
    }

    /// Set whether layout tests should be generated.
    pub fn layout_tests(mut self, doit: bool) -> Self {
        self.options.layout_tests = doit;
        self
    }

    /// Set whether `Debug` should be implemented, if it can not be derived automatically.
    pub fn impl_debug(mut self, doit: bool) -> Self {
        self.options.impl_debug = doit;
        self
    }

    /// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
    pub fn impl_partialeq(mut self, doit: bool) -> Self {
        self.options.impl_partialeq = doit;
        self
    }

    /// Set whether `Copy` should be derived by default.
    pub fn derive_copy(mut self, doit: bool) -> Self {
        self.options.derive_copy = doit;
        self
    }

    /// Set whether `Debug` should be derived by default.
    pub fn derive_debug(mut self, doit: bool) -> Self {
        self.options.derive_debug = doit;
        self
    }

    /// Set whether `Default` should be derived by default.
    pub fn derive_default(mut self, doit: bool) -> Self {
        self.options.derive_default = doit;
        self
    }

    /// Set whether `Hash` should be derived by default.
    pub fn derive_hash(mut self, doit: bool) -> Self {
        self.options.derive_hash = doit;
        self
    }

    /// Set whether `PartialOrd` should be derived by default.
    /// If we don't compute partialord, we also cannot compute
    /// ord. Set the derive_ord to `false` when doit is `false`.
    pub fn derive_partialord(mut self, doit: bool) -> Self {
        self.options.derive_partialord = doit;
        if !doit {
            self.options.derive_ord = false;
        }
        self
    }

    /// Set whether `Ord` should be derived by default.
    /// We can't compute `Ord` without computing `PartialOrd`,
    /// so we set the same option to derive_partialord.
    pub fn derive_ord(mut self, doit: bool) -> Self {
        self.options.derive_ord = doit;
        self.options.derive_partialord = doit;
        self
    }

    /// Set whether `PartialEq` should be derived by default.
    ///
    /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
    /// `Eq` is also disabled when `doit` is `false`.
    pub fn derive_partialeq(mut self, doit: bool) -> Self {
        self.options.derive_partialeq = doit;
        if !doit {
            self.options.derive_eq = false;
        }
        self
    }

    /// Set whether `Eq` should be derived by default.
    ///
    /// We can't derive `Eq` without also deriving `PartialEq`, so we also
    /// enable deriving `PartialEq` when `doit` is `true`.
    pub fn derive_eq(mut self, doit: bool) -> Self {
        self.options.derive_eq = doit;
        if doit {
            self.options.derive_partialeq = doit;
        }
        self
    }

    /// Set whether or not to time bindgen phases, and print information to
    /// stderr.
    pub fn time_phases(mut self, doit: bool) -> Self {
        self.options.time_phases = doit;
        self
    }

    /// Emit Clang AST.
    pub fn emit_clang_ast(mut self) -> Builder {
        self.options.emit_ast = true;
        self
    }

    /// Emit IR.
    pub fn emit_ir(mut self) -> Builder {
        self.options.emit_ir = true;
        self
    }

    /// Enable C++ namespaces.
    pub fn enable_cxx_namespaces(mut self) -> Builder {
        self.options.enable_cxx_namespaces = true;
        self
    }

    /// Enable detecting must_use attributes on C functions.
    ///
    /// This is quite slow in some cases (see #1465), so it's disabled by
    /// default.
    ///
    /// Note that for this to do something meaningful for now at least, the rust
    /// target version has to have support for `#[must_use]`.
    pub fn enable_function_attribute_detection(mut self) -> Self {
        self.options.enable_function_attribute_detection = true;
        self
    }

    /// Disable name auto-namespacing.
    ///
    /// By default, bindgen mangles names like `foo::bar::Baz` to look like
    /// `foo_bar_Baz` instead of just `Baz`.
    ///
    /// This method disables that behavior.
    ///
    /// Note that this intentionally does not change the names used for
    /// allowlisting and blocklisting, which should still be mangled with the
    /// namespaces.
    ///
    /// Note, also, that this option may cause bindgen to generate duplicate
    /// names.
    pub fn disable_name_namespacing(mut self) -> Builder {
        self.options.disable_name_namespacing = true;
        self
    }

    /// Disable nested struct naming.
    ///
    /// The following structs have different names for C and C++. In case of C
    /// they are visible as `foo` and `bar`. In case of C++ they are visible as
    /// `foo` and `foo::bar`.
    ///
    /// ```c
    /// struct foo {
    ///     struct bar {
    ///     } b;
    /// };
    /// ```
    ///
    /// Bindgen wants to avoid duplicate names by default so it follows C++ naming
    /// and it generates `foo`/`foo_bar` instead of just `foo`/`bar`.
    ///
    /// This method disables this behavior and it is indented to be used only
    /// for headers that were written for C.
    pub fn disable_nested_struct_naming(mut self) -> Builder {
        self.options.disable_nested_struct_naming = true;
        self
    }

    /// Treat inline namespaces conservatively.
    ///
    /// This is tricky, because in C++ is technically legal to override an item
    /// defined in an inline namespace:
    ///
    /// ```cpp
    /// inline namespace foo {
    ///     using Bar = int;
    /// }
    /// using Bar = long;
    /// ```
    ///
    /// Even though referencing `Bar` is a compiler error.
    ///
    /// We want to support this (arguably esoteric) use case, but we don't want
    /// to make the rest of bindgen users pay an usability penalty for that.
    ///
    /// To support this, we need to keep all the inline namespaces around, but
    /// then bindgen usage is a bit more difficult, because you cannot
    /// reference, e.g., `std::string` (you'd need to use the proper inline
    /// namespace).
    ///
    /// We could complicate a lot of the logic to detect name collisions, and if
    /// not detected generate a `pub use inline_ns::*` or something like that.
    ///
    /// That's probably something we can do if we see this option is needed in a
    /// lot of cases, to improve it's usability, but my guess is that this is
    /// not going to be too useful.
    pub fn conservative_inline_namespaces(mut self) -> Builder {
        self.options.conservative_inline_namespaces = true;
        self
    }

    /// Whether inline functions should be generated or not.
    ///
    /// Note that they will usually not work. However you can use
    /// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
    /// responsible of compiling the library to make them callable.
    pub fn generate_inline_functions(mut self, doit: bool) -> Self {
        self.options.generate_inline_functions = doit;
        self
    }

    /// Ignore functions.
    pub fn ignore_functions(mut self) -> Builder {
        self.options.codegen_config.remove(CodegenConfig::FUNCTIONS);
        self
    }

    /// Ignore methods.
    pub fn ignore_methods(mut self) -> Builder {
        self.options.codegen_config.remove(CodegenConfig::METHODS);
        self
    }

    /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
    #[deprecated(note = "please use `rust_target` instead")]
    pub fn unstable_rust(self, doit: bool) -> Self {
        let rust_target = if doit {
            RustTarget::Nightly
        } else {
            LATEST_STABLE_RUST
        };
        self.rust_target(rust_target)
    }

    /// Use core instead of libstd in the generated bindings.
    pub fn use_core(mut self) -> Builder {
        self.options.use_core = true;
        self
    }

    /// Use the given prefix for the raw types instead of `::std::os::raw`.
    pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
        self.options.ctypes_prefix = Some(prefix.into());
        self
    }

    /// Use the given prefix for the anon fields.
    pub fn anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
        self.options.anon_fields_prefix = prefix.into();
        self
    }

    /// Allows configuring types in different situations, see the
    /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
    pub fn parse_callbacks(
        mut self,
        cb: Box<dyn callbacks::ParseCallbacks>,
    ) -> Self {
        self.options.parse_callbacks = Some(cb);
        self
    }

    /// Choose what to generate using a
    /// [`CodegenConfig`](./struct.CodegenConfig.html).
    pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
        self.options.codegen_config = config;
        self
    }

    /// Whether to detect include paths using clang_sys.
    pub fn detect_include_paths(mut self, doit: bool) -> Self {
        self.options.detect_include_paths = doit;
        self
    }

    /// Whether to try to fit macro constants to types smaller than u32/i32
    pub fn fit_macro_constants(mut self, doit: bool) -> Self {
        self.options.fit_macro_constants = doit;
        self
    }

    /// Prepend the enum name to constant or newtype variants.
    pub fn prepend_enum_name(mut self, doit: bool) -> Self {
        self.options.prepend_enum_name = doit;
        self
    }

    /// Set whether `size_t` should be translated to `usize` automatically.
    pub fn size_t_is_usize(mut self, is: bool) -> Self {
        self.options.size_t_is_usize = is;
        self
    }

    /// Set whether rustfmt should format the generated bindings.
    pub fn rustfmt_bindings(mut self, doit: bool) -> Self {
        self.options.rustfmt_bindings = doit;
        self
    }

    /// Set whether we should record matched items in our regex sets.
    pub fn record_matches(mut self, doit: bool) -> Self {
        self.options.record_matches = doit;
        self
    }

    /// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt
    /// options are used.
    pub fn rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self {
        self = self.rustfmt_bindings(true);
        self.options.rustfmt_configuration_file = path;
        self
    }

    /// Sets an explicit path to rustfmt, to be used when rustfmt is enabled.
    pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
        self.options.rustfmt_path = Some(path.into());
        self
    }

    /// Generate the Rust bindings using the options built up thus far.
    pub fn generate(mut self) -> Result<Bindings, ()> {
        // Add any extra arguments from the environment to the clang command line.
        if let Some(extra_clang_args) =
            env::var("BINDGEN_EXTRA_CLANG_ARGS").ok()
        {
            // Try to parse it with shell quoting. If we fail, make it one single big argument.
            if let Some(strings) = shlex::split(&extra_clang_args) {
                self.options.clang_args.extend(strings);
            } else {
                self.options.clang_args.push(extra_clang_args);
            };
        }

        // Transform input headers to arguments on the clang command line.
        self.options.input_header = self.input_headers.pop();
        self.options
            .clang_args
            .extend(self.input_headers.drain(..).flat_map(|header| {
                iter::once("-include".into()).chain(iter::once(header))
            }));

        self.options.input_unsaved_files.extend(
            self.input_header_contents
                .drain(..)
                .map(|(name, contents)| {
                    clang::UnsavedFile::new(&name, &contents)
                }),
        );

        Bindings::generate(self.options)
    }

    /// Preprocess and dump the input header files to disk.
    ///
    /// This is useful when debugging bindgen, using C-Reduce, or when filing
    /// issues. The resulting file will be named something like `__bindgen.i` or
    /// `__bindgen.ii`
    pub fn dump_preprocessed_input(&self) -> io::Result<()> {
        let clang =
            clang_sys::support::Clang::find(None, &[]).ok_or_else(|| {
                io::Error::new(
                    io::ErrorKind::Other,
                    "Cannot find clang executable",
                )
            })?;

        // The contents of a wrapper file that includes all the input header
        // files.
        let mut wrapper_contents = String::new();

        // Whether we are working with C or C++ inputs.
        let mut is_cpp = args_are_cpp(&self.options.clang_args);

        // For each input header, add `#include "$header"`.
        for header in &self.input_headers {
            is_cpp |= file_is_cpp(header);

            wrapper_contents.push_str("#include \"");
            wrapper_contents.push_str(header);
            wrapper_contents.push_str("\"\n");
        }

        // For each input header content, add a prefix line of `#line 0 "$name"`
        // followed by the contents.
        for &(ref name, ref contents) in &self.input_header_contents {
            is_cpp |= file_is_cpp(name);

            wrapper_contents.push_str("#line 0 \"");
            wrapper_contents.push_str(name);
            wrapper_contents.push_str("\"\n");
            wrapper_contents.push_str(contents);
        }

        let wrapper_path = PathBuf::from(if is_cpp {
            "__bindgen.cpp"
        } else {
            "__bindgen.c"
        });

        {
            let mut wrapper_file = File::create(&wrapper_path)?;
            wrapper_file.write_all(wrapper_contents.as_bytes())?;
        }

        let mut cmd = Command::new(&clang.path);
        cmd.arg("-save-temps")
            .arg("-E")
            .arg("-C")
            .arg("-c")
            .arg(&wrapper_path)
            .stdout(Stdio::piped());

        for a in &self.options.clang_args {
            cmd.arg(a);
        }

        let mut child = cmd.spawn()?;

        let mut preprocessed = child.stdout.take().unwrap();
        let mut file = File::create(if is_cpp {
            "__bindgen.ii"
        } else {
            "__bindgen.i"
        })?;
        io::copy(&mut preprocessed, &mut file)?;

        if child.wait()?.success() {
            Ok(())
        } else {
            Err(io::Error::new(
                io::ErrorKind::Other,
                "clang exited with non-zero status",
            ))
        }
    }

    /// Don't derive `PartialEq` for a given type. Regular
    /// expressions are supported.
    pub fn no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.no_partialeq_types.insert(arg.into());
        self
    }

    /// Don't derive `Copy` for a given type. Regular
    /// expressions are supported.
    pub fn no_copy<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.no_copy_types.insert(arg.into());
        self
    }

    /// Don't derive `Debug` for a given type. Regular
    /// expressions are supported.
    pub fn no_debug<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.no_debug_types.insert(arg.into());
        self
    }

    /// Don't derive/impl `Default` for a given type. Regular
    /// expressions are supported.
    pub fn no_default<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.no_default_types.insert(arg.into());
        self
    }

    /// Don't derive `Hash` for a given type. Regular
    /// expressions are supported.
    pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.no_hash_types.insert(arg.into());
        self
    }

    /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut)
    pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
        self.options.array_pointers_in_arguments = doit;
        self
    }

    /// Set the wasm import module name
    pub fn wasm_import_module_name<T: Into<String>>(
        mut self,
        import_name: T,
    ) -> Self {
        self.options.wasm_import_module_name = Some(import_name.into());
        self
    }

    /// Specify the dynamic library name if we are generating bindings for a shared library.
    pub fn dynamic_library_name<T: Into<String>>(
        mut self,
        dynamic_library_name: T,
    ) -> Self {
        self.options.dynamic_library_name = Some(dynamic_library_name.into());
        self
    }

    /// Require successful linkage for all routines in a shared library.
    /// This allows us to optimize function calls by being able to safely assume function pointers
    /// are valid.
    pub fn dynamic_link_require_all(mut self, req: bool) -> Self {
        self.options.dynamic_link_require_all = req;
        self
    }

    /// Generate bindings as `pub` only if the bound item is publically accessible by C++.
    pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self {
        self.options.respect_cxx_access_specs = doit;
        self
    }

    /// Always translate enum integer types to native Rust integer types.
    ///
    /// This will result in enums having types such as `u32` and `i16` instead
    /// of `c_uint` and `c_short`. Types for Rustified enums are always
    /// translated.
    pub fn translate_enum_integer_types(mut self, doit: bool) -> Self {
        self.options.translate_enum_integer_types = doit;
        self
    }
}

/// Configuration options for generated bindings.
#[derive(Debug)]
struct BindgenOptions {
    /// The set of types that have been blocklisted and should not appear
    /// anywhere in the generated code.
    blocklisted_types: RegexSet,

    /// The set of functions that have been blocklisted and should not appear
    /// in the generated code.
    blocklisted_functions: RegexSet,

    /// The set of items, regardless of item-type, that have been
    /// blocklisted and should not appear in the generated code.
    blocklisted_items: RegexSet,

    /// The set of types that should be treated as opaque structures in the
    /// generated code.
    opaque_types: RegexSet,

    /// The explicit rustfmt path.
    rustfmt_path: Option<PathBuf>,

    /// The set of types that we should have bindings for in the generated
    /// code.
    ///
    /// This includes all types transitively reachable from any type in this
    /// set. One might think of allowlisted types/vars/functions as GC roots,
    /// and the generated Rust code as including everything that gets marked.
    allowlisted_types: RegexSet,

    /// Allowlisted functions. See docs for `allowlisted_types` for more.
    allowlisted_functions: RegexSet,

    /// Allowlisted variables. See docs for `allowlisted_types` for more.
    allowlisted_vars: RegexSet,

    /// The default style of code to generate for enums
    default_enum_style: codegen::EnumVariation,

    /// The enum patterns to mark an enum as a bitfield
    /// (newtype with bitwise operations).
    bitfield_enums: RegexSet,

    /// The enum patterns to mark an enum as a newtype.
    newtype_enums: RegexSet,

    /// The enum patterns to mark an enum as a Rust enum.
    rustified_enums: RegexSet,

    /// The enum patterns to mark an enum as a non-exhaustive Rust enum.
    rustified_non_exhaustive_enums: RegexSet,

    /// The enum patterns to mark an enum as a module of constants.
    constified_enum_modules: RegexSet,

    /// The enum patterns to mark an enum as a set of constants.
    constified_enums: RegexSet,

    /// The default type for C macro constants.
    default_macro_constant_type: codegen::MacroTypeVariation,

    /// The default style of code to generate for typedefs.
    default_alias_style: codegen::AliasVariation,

    /// Typedef patterns that will use regular type aliasing.
    type_alias: RegexSet,

    /// Typedef patterns that will be aliased by creating a new struct.
    new_type_alias: RegexSet,

    /// Typedef patterns that will be wrapped in a new struct and have
    /// Deref and Deref to their aliased type.
    new_type_alias_deref: RegexSet,

    /// Whether we should generate builtins or not.
    builtins: bool,

    /// True if we should dump the Clang AST for debugging purposes.
    emit_ast: bool,

    /// True if we should dump our internal IR for debugging purposes.
    emit_ir: bool,

    /// Output graphviz dot file.
    emit_ir_graphviz: Option<String>,

    /// True if we should emulate C++ namespaces with Rust modules in the
    /// generated bindings.
    enable_cxx_namespaces: bool,

    /// True if we should try to find unexposed attributes in functions, in
    /// order to be able to generate #[must_use] attributes in Rust.
    enable_function_attribute_detection: bool,

    /// True if we should avoid mangling names with namespaces.
    disable_name_namespacing: bool,

    /// True if we should avoid generating nested struct names.
    disable_nested_struct_naming: bool,

    /// True if we should avoid embedding version identifiers into source code.
    disable_header_comment: bool,

    /// True if we should generate layout tests for generated structures.
    layout_tests: bool,

    /// True if we should implement the Debug trait for C/C++ structures and types
    /// that do not support automatically deriving Debug.
    impl_debug: bool,

    /// True if we should implement the PartialEq trait for C/C++ structures and types
    /// that do not support automatically deriving PartialEq.
    impl_partialeq: bool,

    /// True if we should derive Copy trait implementations for C/C++ structures
    /// and types.
    derive_copy: bool,

    /// True if we should derive Debug trait implementations for C/C++ structures
    /// and types.
    derive_debug: bool,

    /// True if we should derive Default trait implementations for C/C++ structures
    /// and types.
    derive_default: bool,

    /// True if we should derive Hash trait implementations for C/C++ structures
    /// and types.
    derive_hash: bool,

    /// True if we should derive PartialOrd trait implementations for C/C++ structures
    /// and types.
    derive_partialord: bool,

    /// True if we should derive Ord trait implementations for C/C++ structures
    /// and types.
    derive_ord: bool,

    /// True if we should derive PartialEq trait implementations for C/C++ structures
    /// and types.
    derive_partialeq: bool,

    /// True if we should derive Eq trait implementations for C/C++ structures
    /// and types.
    derive_eq: bool,

    /// True if we should avoid using libstd to use libcore instead.
    use_core: bool,

    /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
    ctypes_prefix: Option<String>,

    /// The prefix for the anon fields.
    anon_fields_prefix: String,

    /// Whether to time the bindgen phases.
    time_phases: bool,

    /// True if we should generate constant names that are **directly** under
    /// namespaces.
    namespaced_constants: bool,

    /// True if we should use MSVC name mangling rules.
    msvc_mangling: bool,

    /// Whether we should convert float types to f32/f64 types.
    convert_floats: bool,

    /// The set of raw lines to prepend to the top-level module of generated
    /// Rust code.
    raw_lines: Vec<String>,

    /// The set of raw lines to prepend to each of the modules.
    ///
    /// This only makes sense if the `enable_cxx_namespaces` option is set.
    module_lines: HashMap<String, Vec<String>>,

    /// The set of arguments to pass straight through to Clang.
    clang_args: Vec<String>,

    /// The input header file.
    input_header: Option<String>,

    /// Unsaved files for input.
    input_unsaved_files: Vec<clang::UnsavedFile>,

    /// A user-provided visitor to allow customizing different kinds of
    /// situations.
    parse_callbacks: Option<Box<dyn callbacks::ParseCallbacks>>,

    /// Which kind of items should we generate? By default, we'll generate all
    /// of them.
    codegen_config: CodegenConfig,

    /// Whether to treat inline namespaces conservatively.
    ///
    /// See the builder method description for more details.
    conservative_inline_namespaces: bool,

    /// Whether to keep documentation comments in the generated output. See the
    /// documentation for more details. Defaults to true.
    generate_comments: bool,

    /// Whether to generate inline functions. Defaults to false.
    generate_inline_functions: bool,

    /// Whether to allowlist types recursively. Defaults to true.
    allowlist_recursively: bool,

    /// Instead of emitting 'use objc;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate objc;'
    objc_extern_crate: bool,

    /// Instead of emitting 'use block;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate block;'
    generate_block: bool,

    /// Instead of emitting 'use block;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate block;'
    block_extern_crate: bool,

    /// Whether to use the clang-provided name mangling. This is true and
    /// probably needed for C++ features.
    ///
    /// However, some old libclang versions seem to return incorrect results in
    /// some cases for non-mangled functions, see [1], so we allow disabling it.
    ///
    /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
    enable_mangling: bool,

    /// Whether to detect include paths using clang_sys.
    detect_include_paths: bool,

    /// Whether to try to fit macro constants into types smaller than u32/i32
    fit_macro_constants: bool,

    /// Whether to prepend the enum name to constant or newtype variants.
    prepend_enum_name: bool,

    /// Version of the Rust compiler to target
    rust_target: RustTarget,

    /// Features to enable, derived from `rust_target`
    rust_features: RustFeatures,

    /// Whether we should record which items in the regex sets ever matched.
    ///
    /// This may be a bit slower, but will enable reporting of unused allowlist
    /// items via the `error!` log.
    record_matches: bool,

    /// Whether `size_t` should be translated to `usize` automatically.
    size_t_is_usize: bool,

    /// Whether rustfmt should format the generated bindings.
    rustfmt_bindings: bool,

    /// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
    /// options are used.
    rustfmt_configuration_file: Option<PathBuf>,

    /// The set of types that we should not derive `PartialEq` for.
    no_partialeq_types: RegexSet,

    /// The set of types that we should not derive `Copy` for.
    no_copy_types: RegexSet,

    /// The set of types that we should not derive `Debug` for.
    no_debug_types: RegexSet,

    /// The set of types that we should not derive/impl `Default` for.
    no_default_types: RegexSet,

    /// The set of types that we should not derive `Hash` for.
    no_hash_types: RegexSet,

    /// Decide if C arrays should be regular pointers in rust or array pointers
    array_pointers_in_arguments: bool,

    /// Wasm import module name.
    wasm_import_module_name: Option<String>,

    /// The name of the dynamic library (if we are generating bindings for a shared library). If
    /// this is None, no dynamic bindings are created.
    dynamic_library_name: Option<String>,

    /// Require successful linkage for all routines in a shared library.
    /// This allows us to optimize function calls by being able to safely assume function pointers
    /// are valid. No effect if `dynamic_library_name` is None.
    dynamic_link_require_all: bool,

    /// Only make generated bindings `pub` if the items would be publically accessible
    /// by C++.
    respect_cxx_access_specs: bool,

    /// Always translate enum integer types to native Rust integer types.
    translate_enum_integer_types: bool,
}

/// TODO(emilio): This is sort of a lie (see the error message that results from
/// removing this), but since we don't share references across panic boundaries
/// it's ok.
impl ::std::panic::UnwindSafe for BindgenOptions {}

impl BindgenOptions {
    fn build(&mut self) {
        let mut regex_sets = [
            &mut self.allowlisted_vars,
            &mut self.allowlisted_types,
            &mut self.allowlisted_functions,
            &mut self.blocklisted_types,
            &mut self.blocklisted_functions,
            &mut self.blocklisted_items,
            &mut self.opaque_types,
            &mut self.bitfield_enums,
            &mut self.constified_enums,
            &mut self.constified_enum_modules,
            &mut self.newtype_enums,
            &mut self.rustified_enums,
            &mut self.rustified_non_exhaustive_enums,
            &mut self.type_alias,
            &mut self.new_type_alias,
            &mut self.new_type_alias_deref,
            &mut self.no_partialeq_types,
            &mut self.no_copy_types,
            &mut self.no_debug_types,
            &mut self.no_default_types,
            &mut self.no_hash_types,
        ];
        let record_matches = self.record_matches;
        for regex_set in &mut regex_sets {
            regex_set.build(record_matches);
        }
    }

    /// Update rust target version
    pub fn set_rust_target(&mut self, rust_target: RustTarget) {
        self.rust_target = rust_target;

        // Keep rust_features synced with rust_target
        self.rust_features = rust_target.into();
    }

    /// Get features supported by target Rust version
    pub fn rust_features(&self) -> RustFeatures {
        self.rust_features
    }
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        let rust_target = RustTarget::default();

        BindgenOptions {
            rust_target,
            rust_features: rust_target.into(),
            blocklisted_types: Default::default(),
            blocklisted_functions: Default::default(),
            blocklisted_items: Default::default(),
            opaque_types: Default::default(),
            rustfmt_path: Default::default(),
            allowlisted_types: Default::default(),
            allowlisted_functions: Default::default(),
            allowlisted_vars: Default::default(),
            default_enum_style: Default::default(),
            bitfield_enums: Default::default(),
            newtype_enums: Default::default(),
            rustified_enums: Default::default(),
            rustified_non_exhaustive_enums: Default::default(),
            constified_enums: Default::default(),
            constified_enum_modules: Default::default(),
            default_macro_constant_type: Default::default(),
            default_alias_style: Default::default(),
            type_alias: Default::default(),
            new_type_alias: Default::default(),
            new_type_alias_deref: Default::default(),
            builtins: false,
            emit_ast: false,
            emit_ir: false,
            emit_ir_graphviz: None,
            layout_tests: true,
            impl_debug: false,
            impl_partialeq: false,
            derive_copy: true,
            derive_debug: true,
            derive_default: false,
            derive_hash: false,
            derive_partialord: false,
            derive_ord: false,
            derive_partialeq: false,
            derive_eq: false,
            enable_cxx_namespaces: false,
            enable_function_attribute_detection: false,
            disable_name_namespacing: false,
            disable_nested_struct_naming: false,
            disable_header_comment: false,
            use_core: false,
            ctypes_prefix: None,
            anon_fields_prefix: DEFAULT_ANON_FIELDS_PREFIX.into(),
            namespaced_constants: true,
            msvc_mangling: false,
            convert_floats: true,
            raw_lines: vec![],
            module_lines: HashMap::default(),
            clang_args: vec![],
            input_header: None,
            input_unsaved_files: vec![],
            parse_callbacks: None,
            codegen_config: CodegenConfig::all(),
            conservative_inline_namespaces: false,
            generate_comments: true,
            generate_inline_functions: false,
            allowlist_recursively: true,
            generate_block: false,
            objc_extern_crate: false,
            block_extern_crate: false,
            enable_mangling: true,
            detect_include_paths: true,
            fit_macro_constants: false,
            prepend_enum_name: true,
            time_phases: false,
            record_matches: true,
            rustfmt_bindings: true,
            size_t_is_usize: false,
            rustfmt_configuration_file: None,
            no_partialeq_types: Default::default(),
            no_copy_types: Default::default(),
            no_debug_types: Default::default(),
            no_default_types: Default::default(),
            no_hash_types: Default::default(),
            array_pointers_in_arguments: false,
            wasm_import_module_name: None,
            dynamic_library_name: None,
            dynamic_link_require_all: false,
            respect_cxx_access_specs: false,
            translate_enum_integer_types: false,
        }
    }
}

#[cfg(feature = "runtime")]
fn ensure_libclang_is_loaded() {
    if clang_sys::is_loaded() {
        return;
    }

    // XXX (issue #350): Ensure that our dynamically loaded `libclang`
    // doesn't get dropped prematurely, nor is loaded multiple times
    // across different threads.

    lazy_static! {
        static ref LIBCLANG: std::sync::Arc<clang_sys::SharedLibrary> = {
            clang_sys::load().expect("Unable to find libclang");
            clang_sys::get_library().expect(
                "We just loaded libclang and it had better still be \
                 here!",
            )
        };
    }

    clang_sys::set_library(Some(LIBCLANG.clone()));
}

#[cfg(not(feature = "runtime"))]
fn ensure_libclang_is_loaded() {}

/// Generated Rust bindings.
#[derive(Debug)]
pub struct Bindings {
    options: BindgenOptions,
    module: proc_macro2::TokenStream,
}

pub(crate) const HOST_TARGET: &'static str =
    include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));

// Some architecture triplets are different between rust and libclang, see #1211
// and duplicates.
fn rust_to_clang_target(rust_target: &str) -> String {
    if rust_target.starts_with("aarch64-apple-") {
        let mut clang_target = "arm64-apple-".to_owned();
        clang_target.push_str(&rust_target["aarch64-apple-".len()..]);
        return clang_target;
    }
    rust_target.to_owned()
}

/// Returns the effective target, and whether it was explicitly specified on the
/// clang flags.
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
    let mut args = clang_args.iter();
    while let Some(opt) = args.next() {
        if opt.starts_with("--target=") {
            let mut split = opt.split('=');
            split.next();
            return (split.next().unwrap().to_owned(), true);
        }

        if opt == "-target" {
            if let Some(target) = args.next() {
                return (target.clone(), true);
            }
        }
    }

    // If we're running from a build script, try to find the cargo target.
    if let Ok(t) = env::var("TARGET") {
        return (rust_to_clang_target(&t), false);
    }

    (rust_to_clang_target(HOST_TARGET), false)
}

impl Bindings {
    /// Generate bindings for the given options.
    pub(crate) fn generate(
        mut options: BindgenOptions,
    ) -> Result<Bindings, ()> {
        ensure_libclang_is_loaded();

        #[cfg(feature = "runtime")]
        debug!(
            "Generating bindings, libclang at {}",
            clang_sys::get_library().unwrap().path().display()
        );
        #[cfg(not(feature = "runtime"))]
        debug!("Generating bindings, libclang linked");

        options.build();

        let (effective_target, explicit_target) =
            find_effective_target(&options.clang_args);

        let is_host_build =
            rust_to_clang_target(HOST_TARGET) == effective_target;

        // NOTE: The is_host_build check wouldn't be sound normally in some
        // cases if we were to call a binary (if you have a 32-bit clang and are
        // building on a 64-bit system for example).  But since we rely on
        // opening libclang.so, it has to be the same architecture and thus the
        // check is fine.
        if !explicit_target && !is_host_build {
            options
                .clang_args
                .insert(0, format!("--target={}", effective_target));
        };

        fn detect_include_paths(options: &mut BindgenOptions) {
            if !options.detect_include_paths {
                return;
            }

            // Filter out include paths and similar stuff, so we don't incorrectly
            // promote them to `-isystem`.
            let clang_args_for_clang_sys = {
                let mut last_was_include_prefix = false;
                options
                    .clang_args
                    .iter()
                    .filter(|arg| {
                        if last_was_include_prefix {
                            last_was_include_prefix = false;
                            return false;
                        }

                        let arg = &**arg;

                        // https://clang.llvm.org/docs/ClangCommandLineReference.html
                        // -isystem and -isystem-after are harmless.
                        if arg == "-I" || arg == "--include-directory" {
                            last_was_include_prefix = true;
                            return false;
                        }

                        if arg.starts_with("-I") ||
                            arg.starts_with("--include-directory=")
                        {
                            return false;
                        }

                        true
                    })
                    .cloned()
                    .collect::<Vec<_>>()
            };

            debug!(
                "Trying to find clang with flags: {:?}",
                clang_args_for_clang_sys
            );

            let clang = match clang_sys::support::Clang::find(
                None,
                &clang_args_for_clang_sys,
            ) {
                None => return,
                Some(clang) => clang,
            };

            debug!("Found clang: {:?}", clang);

            // Whether we are working with C or C++ inputs.
            let is_cpp = args_are_cpp(&options.clang_args) ||
                options
                    .input_header
                    .as_ref()
                    .map_or(false, |i| file_is_cpp(&i));

            let search_paths = if is_cpp {
                clang.cpp_search_paths
            } else {
                clang.c_search_paths
            };

            if let Some(search_paths) = search_paths {
                for path in search_paths.into_iter() {
                    if let Ok(path) = path.into_os_string().into_string() {
                        options.clang_args.push("-isystem".to_owned());
                        options.clang_args.push(path);
                    }
                }
            }
        }

        detect_include_paths(&mut options);

        #[cfg(unix)]
        fn can_read(perms: &std::fs::Permissions) -> bool {
            use std::os::unix::fs::PermissionsExt;
            perms.mode() & 0o444 > 0
        }

        #[cfg(not(unix))]
        fn can_read(_: &std::fs::Permissions) -> bool {
            true
        }

        if let Some(h) = options.input_header.as_ref() {
            if let Ok(md) = std::fs::metadata(h) {
                if md.is_dir() {
                    eprintln!("error: '{}' is a folder", h);
                    return Err(());
                }
                if !can_read(&md.permissions()) {
                    eprintln!(
                        "error: insufficient permissions to read '{}'",
                        h
                    );
                    return Err(());
                }
                options.clang_args.push(h.clone())
            } else {
                eprintln!("error: header '{}' does not exist.", h);
                return Err(());
            }
        }

        for (idx, f) in options.input_unsaved_files.iter().enumerate() {
            if idx != 0 || options.input_header.is_some() {
                options.clang_args.push("-include".to_owned());
            }
            options.clang_args.push(f.name.to_str().unwrap().to_owned())
        }

        debug!("Fixed-up options: {:?}", options);

        let time_phases = options.time_phases;
        let mut context = BindgenContext::new(options);

        if is_host_build {
            debug_assert_eq!(
                context.target_pointer_size(),
                std::mem::size_of::<*mut ()>(),
                "{:?} {:?}",
                effective_target,
                HOST_TARGET
            );
        }

        {
            let _t = time::Timer::new("parse").with_output(time_phases);
            parse(&mut context)?;
        }

        let (items, options) = codegen::codegen(context);

        Ok(Bindings {
            options,
            module: quote! {
                #( #items )*
            },
        })
    }

    /// Convert these bindings into source text (with raw lines prepended).
    pub fn to_string(&self) -> String {
        let mut bytes = vec![];
        self.write(Box::new(&mut bytes) as Box<dyn Write>)
            .expect("writing to a vec cannot fail");
        String::from_utf8(bytes)
            .expect("we should only write bindings that are valid utf-8")
    }

    /// Write these bindings as source text to a file.
    pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
        let file = OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open(path.as_ref())?;
        self.write(Box::new(file))?;
        Ok(())
    }

    /// Write these bindings as source text to the given `Write`able.
    pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
        if !self.options.disable_header_comment {
            let version = option_env!("CARGO_PKG_VERSION");
            let header = format!(
                "/* automatically generated by rust-bindgen {} */\n\n",
                version.unwrap_or("(unknown version)")
            );
            writer.write_all(header.as_bytes())?;
        }

        for line in self.options.raw_lines.iter() {
            writer.write_all(line.as_bytes())?;
            writer.write_all("\n".as_bytes())?;
        }

        if !self.options.raw_lines.is_empty() {
            writer.write_all("\n".as_bytes())?;
        }

        let bindings = self.module.to_string();

        match self.rustfmt_generated_string(&bindings) {
            Ok(rustfmt_bindings) => {
                writer.write_all(rustfmt_bindings.as_bytes())?;
            }
            Err(err) => {
                eprintln!(
                    "Failed to run rustfmt: {} (non-fatal, continuing)",
                    err
                );
                writer.write_all(bindings.as_bytes())?;
            }
        }
        Ok(())
    }

    /// Gets the rustfmt path to rustfmt the generated bindings.
    fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> {
        debug_assert!(self.options.rustfmt_bindings);
        if let Some(ref p) = self.options.rustfmt_path {
            return Ok(Cow::Borrowed(p));
        }
        if let Ok(rustfmt) = env::var("RUSTFMT") {
            return Ok(Cow::Owned(rustfmt.into()));
        }
        #[cfg(feature = "which-rustfmt")]
        match which::which("rustfmt") {
            Ok(p) => Ok(Cow::Owned(p)),
            Err(e) => {
                Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
            }
        }
        #[cfg(not(feature = "which-rustfmt"))]
        // No rustfmt binary was specified, so assume that the binary is called
        // "rustfmt" and that it is in the user's PATH.
        Ok(Cow::Owned("rustfmt".into()))
    }

    /// Checks if rustfmt_bindings is set and runs rustfmt on the string
    fn rustfmt_generated_string<'a>(
        &self,
        source: &'a str,
    ) -> io::Result<Cow<'a, str>> {
        let _t = time::Timer::new("rustfmt_generated_string")
            .with_output(self.options.time_phases);

        if !self.options.rustfmt_bindings {
            return Ok(Cow::Borrowed(source));
        }

        let rustfmt = self.rustfmt_path()?;
        let mut cmd = Command::new(&*rustfmt);

        cmd.stdin(Stdio::piped()).stdout(Stdio::piped());

        if let Some(path) = self
            .options
            .rustfmt_configuration_file
            .as_ref()
            .and_then(|f| f.to_str())
        {
            cmd.args(&["--config-path", path]);
        }

        let mut child = cmd.spawn()?;
        let mut child_stdin = child.stdin.take().unwrap();
        let mut child_stdout = child.stdout.take().unwrap();

        let source = source.to_owned();

        // Write to stdin in a new thread, so that we can read from stdout on this
        // thread. This keeps the child from blocking on writing to its stdout which
        // might block us from writing to its stdin.
        let stdin_handle = ::std::thread::spawn(move || {
            let _ = child_stdin.write_all(source.as_bytes());
            source
        });

        let mut output = vec![];
        io::copy(&mut child_stdout, &mut output)?;

        let status = child.wait()?;
        let source = stdin_handle.join().expect(
            "The thread writing to rustfmt's stdin doesn't do \
             anything that could panic",
        );

        match String::from_utf8(output) {
            Ok(bindings) => match status.code() {
                Some(0) => Ok(Cow::Owned(bindings)),
                Some(2) => Err(io::Error::new(
                    io::ErrorKind::Other,
                    "Rustfmt parsing errors.".to_string(),
                )),
                Some(3) => {
                    warn!("Rustfmt could not format some lines.");
                    Ok(Cow::Owned(bindings))
                }
                _ => Err(io::Error::new(
                    io::ErrorKind::Other,
                    "Internal rustfmt error".to_string(),
                )),
            },
            _ => Ok(Cow::Owned(source)),
        }
    }
}

/// Determines whether the given cursor is in any of the files matched by the
/// options.
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
    ctx.options().builtins || !cursor.is_builtin()
}

/// Parse one `Item` from the Clang cursor.
fn parse_one(
    ctx: &mut BindgenContext,
    cursor: clang::Cursor,
    parent: Option<ItemId>,
) -> clang_sys::CXChildVisitResult {
    if !filter_builtins(ctx, &cursor) {
        return CXChildVisit_Continue;
    }

    use clang_sys::CXChildVisit_Continue;
    match Item::parse(cursor, parent, ctx) {
        Ok(..) => {}
        Err(ParseError::Continue) => {}
        Err(ParseError::Recurse) => {
            cursor.visit(|child| parse_one(ctx, child, parent));
        }
    }
    CXChildVisit_Continue
}

/// Parse the Clang AST into our `Item` internal representation.
fn parse(context: &mut BindgenContext) -> Result<(), ()> {
    use clang_sys::*;

    let mut any_error = false;
    for d in context.translation_unit().diags().iter() {
        let msg = d.format();
        let is_err = d.severity() >= CXDiagnostic_Error;
        eprintln!("{}, err: {}", msg, is_err);
        any_error |= is_err;
    }

    if any_error {
        return Err(());
    }

    let cursor = context.translation_unit().cursor();

    if context.options().emit_ast {
        fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
            if !cur.is_builtin() {
                clang::ast_dump(&cur, 0)
            } else {
                CXChildVisit_Continue
            }
        }
        cursor.visit(|cur| dump_if_not_builtin(&cur));
    }

    let root = context.root_module();
    context.with_module(root, |context| {
        cursor.visit(|cursor| parse_one(context, cursor, None))
    });

    assert!(
        context.current_module() == context.root_module(),
        "How did this happen?"
    );
    Ok(())
}

/// Extracted Clang version data
#[derive(Debug)]
pub struct ClangVersion {
    /// Major and minor semver, if parsing was successful
    pub parsed: Option<(u32, u32)>,
    /// full version string
    pub full: String,
}

/// Get the major and the minor semver numbers of Clang's version
pub fn clang_version() -> ClangVersion {
    ensure_libclang_is_loaded();

    //Debian clang version 11.0.1-2
    let raw_v: String = clang::extract_clang_version();
    let split_v: Option<Vec<&str>> = raw_v
        .split_whitespace()
        .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
        .next()
        .map(|v| v.split('.').collect());
    match split_v {
        Some(v) => {
            if v.len() >= 2 {
                let maybe_major = v[0].parse::<u32>();
                let maybe_minor = v[1].parse::<u32>();
                match (maybe_major, maybe_minor) {
                    (Ok(major), Ok(minor)) => {
                        return ClangVersion {
                            parsed: Some((major, minor)),
                            full: raw_v.clone(),
                        }
                    }
                    _ => {}
                }
            }
        }
        None => {}
    };
    ClangVersion {
        parsed: None,
        full: raw_v.clone(),
    }
}

/// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
/// line
///
/// When running in side a `build.rs` script, this can be used to make cargo invalidate the
/// generated bindings whenever any of the files included from the header change:
/// ```
/// use bindgen::builder;
/// let bindings = builder()
///     .header("path/to/input/header")
///     .parse_callbacks(Box::new(bindgen::CargoCallbacks))
///     .generate();
/// ```
#[derive(Debug)]
pub struct CargoCallbacks;

impl callbacks::ParseCallbacks for CargoCallbacks {
    fn include_file(&self, filename: &str) {
        println!("cargo:rerun-if-changed={}", filename);
    }
}

/// Test command_line_flag function.
#[test]
fn commandline_flag_unit_test_function() {
    //Test 1
    let bindings = crate::builder();
    let command_line_flags = bindings.command_line_flags();

    let test_cases = vec![
        "--rust-target",
        "--no-derive-default",
        "--generate",
        "functions,types,vars,methods,constructors,destructors",
    ]
    .iter()
    .map(|&x| x.into())
    .collect::<Vec<String>>();

    assert!(test_cases
        .iter()
        .all(|ref x| command_line_flags.contains(x),));

    //Test 2
    let bindings = crate::builder()
        .header("input_header")
        .allowlist_type("Distinct_Type")
        .allowlist_function("safe_function");

    let command_line_flags = bindings.command_line_flags();
    let test_cases = vec![
        "--rust-target",
        "input_header",
        "--no-derive-default",
        "--generate",
        "functions,types,vars,methods,constructors,destructors",
        "--allowlist-type",
        "Distinct_Type",
        "--allowlist-function",
        "safe_function",
    ]
    .iter()
    .map(|&x| x.into())
    .collect::<Vec<String>>();
    println!("{:?}", command_line_flags);

    assert!(test_cases
        .iter()
        .all(|ref x| command_line_flags.contains(x),));
}

#[test]
fn test_rust_to_clang_target() {
    assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios");
}
