//! 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.

#![deny(missing_docs)]
#![deny(warnings)]
#![deny(unused_extern_crates)]

// We internally use the deprecated BindgenOptions all over the place. Once we
// remove its `pub` declaration, we can un-deprecate it and remove this pragma.
#![allow(deprecated)]

// To avoid rather annoying warnings when matching with CXCursor_xxx as a
// constant.
#![allow(non_upper_case_globals)]

#[macro_use]
#[allow(unused_extern_crates)]
extern crate cfg_if;
extern crate cexpr;
extern crate syntex_syntax as syntax;
extern crate aster;
extern crate quasi;
extern crate clang_sys;
extern crate peeking_take_while;
extern crate regex;
#[macro_use]
extern crate lazy_static;

#[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_if! {
            if #[cfg(feature = "testing_only_docs")] {
                pub mod $doc_mod_name {
                    //! Autogenerated documentation module.
                    pub use super::$m::*;
                }
            } else {
            }
        }
    };
}

mod clang;
mod ir;
mod parse;
mod regex_set;
mod uses;

pub mod callbacks;

#[cfg(rustfmt)]
mod codegen;

doc_mod!(clang, clang_docs);
doc_mod!(ir, ir_docs);
doc_mod!(parse, parse_docs);
doc_mod!(regex_set, regex_set_docs);
doc_mod!(uses, uses_docs);

mod codegen {
    include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
}

use ir::context::{BindgenContext, ItemId};
use ir::item::Item;
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;

use std::fs::OpenOptions;
use std::io::{self, Write};
use std::path::Path;
use std::sync::Arc;

use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::print::pp::eof;
use syntax::print::pprust;
use syntax::ptr::P;

/// A type used to indicate which kind of items do we have to generate.
///
/// TODO(emilio): Use `bitflags!`
#[derive(Debug, Clone)]
pub struct CodegenConfig {
    /// Whether to generate functions.
    pub functions: bool,
    /// Whether to generate types.
    pub types: bool,
    /// Whether to generate constants.
    pub vars: bool,
    /// Whether to generate methods.
    pub methods: bool,
    /// Whether to generate constructors.
    pub constructors: bool,
    /// Whether to generate destructors.
    pub destructors: bool,
}

impl CodegenConfig {
    /// Generate all kinds of items.
    pub fn all() -> Self {
        CodegenConfig {
            functions: true,
            types: true,
            vars: true,
            methods: true,
            constructors: true,
            destructors: true,
        }
    }

    /// Generate nothing.
    pub fn nothing() -> Self {
        CodegenConfig {
            functions: false,
            types: false,
            vars: false,
            methods: false,
            constructors: false,
            destructors: false,
        }
    }
}

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 = try!(builder().header("path/to/input/header")
///                              .whitelisted_type("SomeCoolClass")
///                              .whitelisted_function("do_some_cool_thing")
///                              .generate());
///
/// // Write the generated bindings to an output file.
/// try!(bindings.write_to_file("path/to/output.rs"));
/// ```
#[derive(Debug,Default)]
pub struct Builder {
    options: BindgenOptions,
}

/// 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(ref header) = self.options.input_header {
            //Positional argument 'header'
            output_vector.push(header.clone().into());
        }

        self.options
            .bitfield_enums
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--bitfield-enum".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        self.options
            .constified_enums
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--constified-enum".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        self.options
            .hidden_types
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--blacklist-type".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        if !self.options.layout_tests {
            output_vector.push("--no-layout-tests".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.generate_comments {
            output_vector.push("--no-doc-comments".into());
        }

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

        if self.options.objc_extern_crate {
            output_vector.push("--objc-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 let Some(ref dummy) = self.options.dummy_uses {
            output_vector.push("--dummy-uses".into());
            output_vector.push(dummy.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.disable_name_namespacing {
            output_vector.push("--disable-name-namespacing".into());
        }

        self.options
            .links
            .iter()
            .map(|&(ref item, _)| {
                     output_vector.push("--framework".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        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("function".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());
        }

        self.options
            .links
            .iter()
            .map(|&(ref item, _)| {
                     output_vector.push("--clang-args".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        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.unstable_rust {
            output_vector.push("--unstable-rust".into());
        }

        self.options
            .opaque_types
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--opaque-type".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        self.options
            .raw_lines
            .iter()
            .map(|item| {
                     output_vector.push("--raw-line".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        self.options
            .links
            .iter()
            .map(|&(ref item, _)| {
                     output_vector.push("--static".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

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

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

        self.options
            .whitelisted_functions
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--whitelist-function".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        self.options
            .whitelisted_types
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--whitelist-type".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        self.options
            .whitelisted_vars
            .get_items()
            .iter()
            .map(|item| {
                     output_vector.push("--whitelist-var".into());
                     output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
                 })
            .count();

        if !self.options.clang_args.is_empty() {
            output_vector.push("--".into());
            self.options
                .clang_args
                .iter()
                .cloned()
                .map(|item| {
                    output_vector.push(item);
                })
                .count();
        }

        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 {
        if let Some(prev_header) = self.options.input_header.take() {
            self.options.clang_args.push("-include".into());
            self.options.clang_args.push(prev_header);
        }

        let header = header.into();
        self.options.input_header = Some(header);
        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 {
        self.options.input_unsaved_files.push(clang::UnsavedFile::new(name, contents));
        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 or
    /// not.
    ///
    /// This ideally will always be true, but it may need to be false until we
    /// implement some processing on comments to work around issues as described
    /// in:
    ///
    /// https://github.com/servo/rust-bindgen/issues/426
    pub fn generate_comments(mut self, doit: bool) -> Self {
        self.options.generate_comments = doit;
        self
    }

    /// Whether to whitelist types recursively or not. Defaults to true.
    ///
    /// This can be used to get bindgen to generate _exactly_ the types you want
    /// in your bindings, and then import other types manually via other means
    /// (like [`raw_line`](#method.raw_line)).
    pub fn whitelist_recursively(mut self, doit: bool) -> Self {
        self.options.whitelist_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
    }

    /// 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/servo/rust-bindgen/issues/528
    pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
        self.options.enable_mangling = doit;
        self
    }

    /// Generate a C/C++ file that includes the header and has dummy uses of
    /// every type defined in the header.
    pub fn dummy_uses<T: Into<String>>(mut self, dummy_uses: T) -> Builder {
        self.options.dummy_uses = Some(dummy_uses.into());
        self
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    pub fn hide_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.hidden_types.insert(arg);
        self
    }

    /// Treat the given type as opaque in the generated bindings. Regular
    /// expressions are supported.
    pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.opaque_types.insert(arg);
        self
    }

    /// Whitelist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    pub fn whitelisted_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_types.insert(arg);
        self
    }

    /// Whitelist the given function so that it (and all types that it
    /// transitively refers to) appears in the generated bindings. Regular
    /// expressions are supported.
    pub fn whitelisted_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_functions.insert(arg);
        self
    }

    /// Whitelist the given variable so that it (and all types that it
    /// transitively refers to) appears in the generated bindings. Regular
    /// expressions are supported.
    pub fn whitelisted_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_vars.insert(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.
    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 being
    /// constant.
    ///
    /// This makes bindgen generate constants instead of enums. Regular
    /// expressions are supported.
    pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.constified_enums.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) -> Builder {
        self.options.raw_lines.push(arg.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
    }

    /// Make the generated bindings link the given shared library.
    pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Default));
        self
    }

    /// Make the generated bindings link the given static library.
    pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Static));
        self
    }

    /// Make the generated bindings link the given framework.
    pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Framework));
        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 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
    }

    /// 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
    }

    /// 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
    /// whitelisting and blacklisting, 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
    }

    /// 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.functions = false;
        self
    }

    /// Ignore methods.
    pub fn ignore_methods(mut self) -> Builder {
        self.options.codegen_config.methods = false;
        self
    }

    /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
    pub fn unstable_rust(mut self, doit: bool) -> Self {
        self.options.unstable_rust = doit;
        self
    }

    /// 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
    }

    /// Allows configuring types in different situations, see the
    /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
    pub fn parse_callbacks(mut self, cb: Box<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
    }

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

    /// Generate the Rust bindings using the options built up thus far.
    pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
        Bindings::generate(self.options, None)
    }
}

/// Configuration options for generated bindings.
///
/// Deprecated: use a `Builder` instead.
#[derive(Debug)]
#[deprecated]
pub struct BindgenOptions {
    /// The set of types that have been blacklisted and should not appear
    /// anywhere in the generated code.
    pub hidden_types: RegexSet,

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

    /// 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 whitelisted types/vars/functions as GC roots,
    /// and the generated Rust code as including everything that gets marked.
    pub whitelisted_types: RegexSet,

    /// Whitelisted functions. See docs for `whitelisted_types` for more.
    pub whitelisted_functions: RegexSet,

    /// Whitelisted variables. See docs for `whitelisted_types` for more.
    pub whitelisted_vars: RegexSet,

    /// The enum patterns to mark an enum as bitfield.
    pub bitfield_enums: RegexSet,

    /// The enum patterns to mark an enum as constant.
    pub constified_enums: RegexSet,

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

    /// The set of libraries we should link in the generated Rust code.
    pub links: Vec<(String, LinkType)>,

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

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

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

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

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

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

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

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

    /// True if we can use unstable Rust code in the bindings, false if we
    /// cannot.
    pub unstable_rust: bool,

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

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

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

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

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

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

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

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

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

    /// Generate a dummy C/C++ file that includes the header and has dummy uses
    /// of all types defined therein. See the `uses` module for more.
    pub dummy_uses: Option<String>,

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

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

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

    /// Wether to keep documentation comments in the generated output. See the
    /// documentation for more details.
    pub generate_comments: bool,

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

    /// Wether to whitelist types recursively. Defaults to true.
    pub whitelist_recursively: bool,

    /// Intead of emitting 'use objc;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate objc;'
    pub objc_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/servo/rust-bindgen/issues/528
    pub enable_mangling: bool,

    /// Whether to prepend the enum name to bitfield or constant variants.
    pub prepend_enum_name: 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) {
        self.whitelisted_vars.build();
        self.whitelisted_types.build();
        self.whitelisted_functions.build();
        self.hidden_types.build();
        self.opaque_types.build();
        self.bitfield_enums.build();
        self.constified_enums.build();
    }
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        BindgenOptions {
            hidden_types: Default::default(),
            opaque_types: Default::default(),
            whitelisted_types: Default::default(),
            whitelisted_functions: Default::default(),
            whitelisted_vars: Default::default(),
            bitfield_enums: Default::default(),
            constified_enums: Default::default(),
            builtins: false,
            links: vec![],
            emit_ast: false,
            emit_ir: false,
            emit_ir_graphviz: None,
            layout_tests: true,
            derive_debug: true,
            derive_default: false,
            enable_cxx_namespaces: false,
            disable_name_namespacing: false,
            unstable_rust: false,
            use_core: false,
            ctypes_prefix: None,
            namespaced_constants: true,
            msvc_mangling: false,
            convert_floats: true,
            raw_lines: vec![],
            clang_args: vec![],
            input_header: None,
            input_unsaved_files: vec![],
            dummy_uses: None,
            parse_callbacks: None,
            codegen_config: CodegenConfig::all(),
            conservative_inline_namespaces: false,
            generate_comments: true,
            generate_inline_functions: false,
            whitelist_recursively: true,
            objc_extern_crate: false,
            enable_mangling: true,
            prepend_enum_name: true,
        }
    }
}

/// The linking type to use with a given library.
///
/// TODO: #104: This is ignored at the moment, but shouldn't be.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LinkType {
    /// Use shared library linking. This is the default.
    Default,
    /// Use static linking.
    Static,
    /// The library is an OSX framework.
    Framework,
}

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: 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()));
}

/// Generated Rust bindings.
#[derive(Debug)]
pub struct Bindings<'ctx> {
    context: BindgenContext<'ctx>,
    module: ast::Mod,
}

impl<'ctx> Bindings<'ctx> {
    /// Generate bindings for the given options.
    ///
    /// Deprecated - use a `Builder` instead
    #[deprecated]
    pub fn generate(mut options: BindgenOptions,
                    span: Option<Span>)
                    -> Result<Bindings<'ctx>, ()> {
        let span = span.unwrap_or(DUMMY_SP);
        ensure_libclang_is_loaded();

        options.build();

        // TODO: Make this path fixup configurable?
        if let Some(clang) = clang_sys::support::Clang::find(None) {
            // If --target is specified, assume caller knows what they're doing
            // and don't mess with include paths for them
            let has_target_arg = options.clang_args
                .iter()
                .rposition(|arg| arg.starts_with("--target"))
                .is_some();
            if !has_target_arg {
                // TODO: distinguish C and C++ paths? C++'s should be enough, I
                // guess.
                if let Some(cpp_search_paths) = clang.cpp_search_paths {
                    for path in cpp_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);
                        }
                    }
                }
            }
        }

        if let Some(h) = options.input_header.as_ref() {
            options.clang_args.push(h.clone())
        }

        for f in options.input_unsaved_files.iter() {
            options.clang_args.push(f.name.to_str().unwrap().to_owned())
        }

        let mut context = BindgenContext::new(options);
        try!(parse(&mut context));

        let module = ast::Mod {
            inner: span,
            items: codegen::codegen(&mut context),
        };

        Ok(Bindings {
            context: context,
            module: module,
        })
    }

    /// Convert these bindings into a Rust AST.
    pub fn into_ast(self) -> Vec<P<ast::Item>> {
        self.module.items
    }

    /// Convert these bindings into source text (with raw lines prepended).
    pub fn to_string(&self) -> String {
        let mut mod_str = vec![];
        {
            let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
            self.write(ref_writer).expect("Could not write bindings to string");
        }
        String::from_utf8(mod_str).unwrap()
    }

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

    /// Write these bindings as source text to the given `Write`able.
    pub fn write<'a>(&self, mut writer: Box<Write + 'a>) -> io::Result<()> {
        try!(writer.write("/* automatically generated by rust-bindgen */\n\n"
            .as_bytes()));

        for line in self.context.options().raw_lines.iter() {
            try!(writer.write(line.as_bytes()));
            try!(writer.write("\n".as_bytes()));
        }
        if !self.context.options().raw_lines.is_empty() {
            try!(writer.write("\n".as_bytes()));
        }

        let mut ps = pprust::rust_printer(writer);
        try!(ps.print_mod(&self.module, &[]));
        try!(ps.print_remaining_comments());
        try!(eof(&mut ps.s));
        ps.s.out.flush()
    }

    /// Generate and write dummy uses of all the types we parsed, if we've been
    /// requested to do so in the options.
    ///
    /// See the `uses` module for more information.
    pub fn write_dummy_uses(&mut self) -> io::Result<()> {
        let file = if let Some(ref dummy_path) =
            self.context.options().dummy_uses {
            Some(try!(OpenOptions::new()
                .write(true)
                .truncate(true)
                .create(true)
                .open(dummy_path)))
        } else {
            None
        };

        if let Some(file) = file {
            try!(uses::generate_dummy_uses(&mut self.context, file));
        }

        Ok(())
    }
}

/// 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.
pub 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;
        println!("{}, 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 semvar, if parsing was successful
    pub parsed: Option<(u32, u32)>,
    /// full version string
    pub full: String,
}

/// Get the major and the minor semvar numbers of Clang's version
pub fn clang_version() -> ClangVersion {
    if !clang_sys::is_loaded() {
        // TODO(emilio): Return meaningful error (breaking).
        clang_sys::load().expect("Unable to find libclang");
    }

    let raw_v: String = clang::extract_clang_version();
    let split_v: Option<Vec<&str>> = raw_v.split_whitespace()
        .nth(2)
        .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(),
    }
}

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

    let test_cases = vec!["--no-derive-default",
                          "--generate", "function,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 = ::builder().header("input_header")
                              .whitelisted_type("Distinct_Type")
                              .whitelisted_function("safe_function");

    let command_line_flags = bindings.command_line_flags();
    let test_cases = vec!["input_header",
                          "--no-derive-default",
                          "--generate", "function,types,vars,methods,constructors,destructors",
                          "--whitelist-type", "Distinct_Type",
                          "--whitelist-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)) );

}
