Skip to content

Commit

Permalink
Explicitly store the set of input headers in the builder
Browse files Browse the repository at this point in the history
Rather than eagerly expanding multiple input headers into `-include <header>`
clang arguments, store them explicitly until we actually go to generate
bindings. Same deal for unsaved file contents.
  • Loading branch information
fitzgen committed Jul 13, 2017
1 parent f0b3432 commit dd456d9
Showing 1 changed file with 38 additions and 21 deletions.
59 changes: 38 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;

use std::fs::OpenOptions;
use std::iter;
use std::io::{self, Write};
use std::path::Path;
use std::sync::Arc;
Expand Down Expand Up @@ -168,6 +169,9 @@ impl Default for CodegenConfig {
#[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).
Expand All @@ -180,9 +184,9 @@ impl 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());
if let Some(header) = self.input_headers.last().cloned() {
// Positional argument 'header'
output_vector.push(header);
}

self.options
Expand Down Expand Up @@ -412,16 +416,19 @@ impl Builder {
})
.count();

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

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.extend(
self.options
.clang_args
.iter()
.cloned()
);
}

if self.input_headers.len() > 1 {
output_vector.extend(self.input_headers[..self.input_headers.len() - 1].iter().cloned());
}

output_vector
Expand Down Expand Up @@ -450,21 +457,15 @@ impl Builder {
/// .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.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 {
self.options.input_unsaved_files.push(clang::UnsavedFile::new(name, contents));
self.input_header_contents.push((name.into(), contents.into()));
self
}

Expand Down Expand Up @@ -794,7 +795,23 @@ impl Builder {
}

/// Generate the Rust bindings using the options built up thus far.
pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
pub fn generate<'ctx>(mut self) -> Result<Bindings<'ctx>, ()> {
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, None)
}
}
Expand Down

0 comments on commit dd456d9

Please sign in to comment.