Skip to content

Commit da69afd

Browse files
committed
Back out docopt.
1 parent cfdf15f commit da69afd

File tree

3 files changed

+117
-132
lines changed

3 files changed

+117
-132
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ quasi_codegen = "0.15"
2323

2424
[dependencies]
2525
clang-sys = "0.8.0"
26-
docopt = "0.6.82"
2726
libc = "0.2"
2827
log = "0.3"
2928
env_logger = "0.3"

src/bin/bindgen.rs

Lines changed: 114 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44
extern crate bindgen;
55
extern crate env_logger;
66
#[macro_use]
7-
extern crate docopt;
8-
#[macro_use]
97
extern crate log;
108
extern crate clang_sys;
119
extern crate rustc_serialize;
1210

1311
use bindgen::{Bindings, BindgenOptions, LinkType};
12+
use std::default::Default;
1413
use std::io;
1514
use std::path;
15+
use std::process;
1616
use std::env;
17-
use std::default::Default;
1817
use std::fs;
1918

2019
const USAGE: &'static str = "
@@ -23,9 +22,7 @@ Usage:
2322
[--link=<lib>...] \
2423
[--static-link=<lib>...] \
2524
[--framework-link=<framework>...] \
26-
[--match=<name>...] \
2725
[--raw-line=<raw>...] \
28-
[--dtor-attr=<attr>...] \
2926
[--opaque-type=<type>...] \
3027
[--blacklist-type=<type>...] \
3128
[--whitelist-type=<type>...] \
@@ -50,18 +47,15 @@ Options:
5047
-o=<output-rust-file> Write bindings to <output-rust-file>
5148
(defaults to stdout)
5249
53-
--match=<name> Only output bindings for definitions from
54-
files whose name contains <name>. If multiple
55-
match options are provided, files matching any
56-
rule are bound to.
57-
5850
--builtins Output bindings for builtin definitions (for
5951
example __builtin_va_list)
6052
6153
--ignore-functions Don't generate bindings for functions and
6254
methods. This is useful when you only care
6355
about struct layouts.
6456
57+
--ignore-methods Avoid generating all kind of methods.
58+
6559
--enable-cxx-namespaces Enable support for C++ namespaces.
6660
6761
--no-type-renaming Don't rename types.
@@ -74,25 +68,9 @@ Options:
7468
--use-msvc-mangling Handle MSVC C++ ABI mangling; requires that
7569
target be set to (i686|x86_64)-pc-win32
7670
77-
--override-enum-type=<type> Override enum type, type name could be
78-
uchar
79-
schar
80-
ushort
81-
sshort
82-
uint
83-
sint
84-
ulong
85-
slong
86-
ulonglong
87-
slonglong
88-
8971
--raw-line=<raw> Add a raw line at the beginning of the output.
90-
--dtor-attr=<attr> Attributes to add to structures with destructor.
91-
--no-class-constants Avoid generating class constants.
9272
--no-unstable-rust Avoid generating unstable rust.
93-
--no-namespaced-constants Avoid generating constants right under namespaces.
9473
--no-bitfield-methods Avoid generating methods for bitfield access.
95-
--ignore-methods Avoid generating all kind of methods.
9674
--opaque-type=<type> Mark a type as opaque.
9775
--blacklist-type=<type> Mark a type as hidden.
9876
--whitelist-type=<type> Whitelist the type. If this set or any other
@@ -110,91 +88,119 @@ Options:
11088
directly through to clang.
11189
";
11290

113-
#[derive(Debug, RustcDecodable)]
114-
struct Args {
115-
arg_input_header: String,
116-
flag_link: Vec<String>,
117-
flag_static_link: Vec<String>,
118-
flag_framework_link: Vec<String>,
119-
flag_o: Option<String>,
120-
flag_match: Vec<String>,
121-
flag_builtins: bool,
122-
flag_ignore_functions: bool,
123-
flag_enable_cxx_namespaces: bool,
124-
flag_no_type_renaming: bool,
125-
flag_allow_unknown_types: bool,
126-
flag_emit_clang_ast: bool,
127-
flag_use_msvc_mangling: bool,
128-
flag_override_enum_type: String,
129-
flag_raw_line: Vec<String>,
130-
flag_dtor_attr: Vec<String>,
131-
flag_no_class_constants: bool,
132-
flag_no_unstable_rust: bool,
133-
flag_no_namespaced_constants: bool,
134-
flag_no_bitfield_methods: bool,
135-
flag_ignore_methods: bool,
136-
flag_opaque_type: Vec<String>,
137-
flag_blacklist_type: Vec<String>,
138-
flag_whitelist_type: Vec<String>,
139-
flag_whitelist_function: Vec<String>,
140-
flag_whitelist_var: Vec<String>,
141-
arg_clang_args: Vec<String>,
142-
}
143-
144-
type ParseResult<T> = Result<T, String>;
145-
146-
impl Into<ParseResult<(BindgenOptions, Box<io::Write>)>> for Args {
147-
fn into(mut self) -> Result<(BindgenOptions, Box<io::Write>), String> {
148-
let mut options: BindgenOptions = Default::default();
149-
150-
for lib in self.flag_link.drain(..) {
151-
options.links.push((lib, LinkType::Default));
152-
}
91+
// FIXME(emilio): Replace this with docopt if/when they fix their exponential
92+
// algorithm for argument parsing.
93+
fn parse_args_or_exit(args: Vec<String>) -> (BindgenOptions, Box<io::Write>) {
94+
let mut options = BindgenOptions::default();
95+
let mut dest_file = None;
96+
let mut source_file = None;
97+
98+
let mut iter = args.into_iter().skip(1);
99+
loop {
100+
let next = match iter.next() {
101+
Some(arg) => arg,
102+
_ => break,
103+
};
153104

154-
for lib in self.flag_static_link.drain(..) {
155-
options.links.push((lib, LinkType::Static));
105+
match &*next {
106+
"-h" | "--help" => {
107+
println!("{}", USAGE);
108+
process::exit(0);
109+
}
110+
"-l" | "--link" => {
111+
let lib = iter.next().expect("--link needs an argument");
112+
options.links.push((lib, LinkType::Default));
113+
}
114+
"--static-link" => {
115+
let lib = iter.next().expect("--static-link needs an argument");
116+
options.links.push((lib, LinkType::Static));
117+
}
118+
"--framework-link" => {
119+
let lib = iter.next().expect("--framework-link needs an argument");
120+
options.links.push((lib, LinkType::Framework));
121+
}
122+
"--raw-line" => {
123+
let line = iter.next().expect("--raw-line needs an argument");
124+
options.raw_lines.push(line);
125+
}
126+
"--opaque-type" => {
127+
let ty_canonical_name = iter.next().expect("--opaque-type expects a type");
128+
options.opaque_types.insert(ty_canonical_name);
129+
}
130+
"--blacklist-type" => {
131+
let ty_canonical_name = iter.next().expect("--blacklist-type expects a type");
132+
options.hidden_types.insert(ty_canonical_name);
133+
}
134+
"--whitelist-type" => {
135+
let ty_pat = iter.next().expect("--whitelist-type expects a type pattern");
136+
options.whitelisted_types.insert(&ty_pat);
137+
}
138+
"--whitelist-function" => {
139+
let function_pat = iter.next().expect("--whitelist-function expects a pattern");
140+
options.whitelisted_functions.insert(&function_pat);
141+
}
142+
"--whitelist-var" => {
143+
let var_pat = iter.next().expect("--whitelist-var expects a pattern");
144+
options.whitelisted_vars.insert(&var_pat);
145+
}
146+
"--" => {
147+
while let Some(clang_arg) = iter.next() {
148+
options.clang_args.push(clang_arg);
149+
}
150+
}
151+
"--output" | "-o" => {
152+
let out_name = iter.next().expect("-o expects a file name");
153+
dest_file = Some(out_name);
154+
}
155+
"--builtins" => {
156+
options.builtins = true;
157+
}
158+
"--ignore-functions" => {
159+
options.ignore_functions = true;
160+
}
161+
"--no-bitfield-methods" => {
162+
options.gen_bitfield_methods = false;
163+
}
164+
"--ignore-methods" => {
165+
options.ignore_methods = true;
166+
}
167+
"--enable-cxx-namespaces" => {
168+
options.enable_cxx_namespaces = true;
169+
}
170+
"--no-type-renaming" => {
171+
options.rename_types = false;
172+
}
173+
"--no-unstable-rust" => {
174+
options.unstable_rust = false;
175+
}
176+
"--emit-clang-ast" => {
177+
options.emit_ast = true;
178+
}
179+
"--use-msvc-mangling" => {
180+
options.msvc_mangling = true;
181+
}
182+
other if source_file.is_none() => {
183+
source_file = Some(other.into());
184+
}
185+
other => {
186+
panic!("Unknown option: \"{}\"", other);
187+
}
156188
}
189+
}
157190

158-
for lib in self.flag_framework_link.drain(..) {
159-
options.links.push((lib, LinkType::Framework));
160-
}
191+
if let Some(source_file) = source_file.take() {
192+
options.clang_args.push(source_file);
193+
}
161194

162-
let out = if let Some(ref path_name) = self.flag_o {
163-
let path = path::Path::new(path_name);
164-
let file = try!(fs::File::create(path).map_err(|_| {
165-
format!("Opening {} failed", path_name)
166-
}));
167-
Box::new(io::BufWriter::new(file)) as Box<io::Write>
168-
} else {
169-
Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
170-
};
195+
let out = if let Some(ref path_name) = dest_file {
196+
let path = path::Path::new(path_name);
197+
let file = fs::File::create(path).expect("Opening out file failed");
198+
Box::new(io::BufWriter::new(file)) as Box<io::Write>
199+
} else {
200+
Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
201+
};
171202

172-
options.match_pat.extend(self.flag_match.drain(..));
173-
options.builtins = self.flag_builtins;
174-
options.ignore_functions = self.flag_ignore_functions;
175-
options.enable_cxx_namespaces = self.flag_enable_cxx_namespaces;
176-
options.rename_types = !self.flag_no_type_renaming;
177-
options.fail_on_unknown_type = !self.flag_allow_unknown_types;
178-
options.emit_ast = self.flag_emit_clang_ast;
179-
options.msvc_mangling = self.flag_use_msvc_mangling;
180-
options.override_enum_ty = self.flag_override_enum_type;
181-
options.raw_lines.extend(self.flag_raw_line.drain(..));
182-
options.dtor_attrs.extend(self.flag_dtor_attr.drain(..));
183-
options.class_constants = !self.flag_no_class_constants;
184-
options.unstable_rust = !self.flag_no_unstable_rust;
185-
options.namespaced_constants = !self.flag_no_namespaced_constants;
186-
options.gen_bitfield_methods = !self.flag_no_bitfield_methods;
187-
options.ignore_methods = self.flag_ignore_methods;
188-
options.opaque_types.extend(self.flag_opaque_type.drain(..));
189-
options.hidden_types.extend(self.flag_blacklist_type.drain(..));
190-
options.whitelisted_types.extend(self.flag_whitelist_type.drain(..));
191-
options.whitelisted_functions.extend(self.flag_whitelist_function.drain(..));
192-
options.whitelisted_vars.extend(self.flag_whitelist_var.drain(..));
193-
options.clang_args.extend(self.arg_clang_args.drain(..));
194-
options.clang_args.push(self.arg_input_header);
195-
196-
Ok((options, out))
197-
}
203+
(options, out)
198204
}
199205

200206
pub fn main() {
@@ -227,17 +233,11 @@ pub fn main() {
227233
}
228234
}
229235

230-
let args: Args = docopt::Docopt::new(USAGE)
231-
.and_then(|d| d.argv(bind_args.iter()).decode())
232-
.unwrap_or_else(|e| e.exit());
233-
234-
let result: ParseResult<_> = args.into();
235-
let (options, out) = result.unwrap_or_else(|msg| {
236-
panic!("Failed to generate_bindings: {:?}", msg);
237-
});
236+
let (options, out) = parse_args_or_exit(bind_args);
238237

239238
let bindings = Bindings::generate(options, None)
240239
.expect("Unable to generate bindings");
240+
241241
bindings.write(out)
242242
.expect("Unable to write bindings to file.");
243243
}

tests/tools/run-bindgen.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,22 @@
1818
[_, bindgen_path, c_path, rust_path] = sys.argv
1919

2020
flags = []
21-
clang_flags = []
2221

2322
with open(sys.argv[2]) as f:
2423
for line in f:
2524
if line.startswith(BINDGEN_FLAGS_PREFIX):
26-
flags = line.strip().split(BINDGEN_FLAGS_PREFIX)[1]
27-
28-
try:
29-
idx = flags.index(CLANG_FLAGS_SEPARATOR)
30-
clang_flags = flags[idx + len(CLANG_FLAGS_SEPARATOR):].split(" ")
31-
flags = flags[:idx]
32-
except ValueError:
33-
pass
34-
35-
flags = flags.split(" ")
25+
flags = line.strip().split(BINDGEN_FLAGS_PREFIX)[1].split(" ")
3626
break
3727

3828
base_command = [bindgen_path, "-o", rust_path]
3929

4030
for line in COMMON_PRELUDE.split("\n"):
41-
flags.append("--raw-line")
42-
flags.append(line)
31+
base_command.append("--raw-line")
32+
base_command.append(line)
4333

4434
base_command.extend(flags)
4535
base_command.append(c_path)
4636

47-
if len(clang_flags):
48-
base_command.append("--")
49-
base_command.extend(clang_flags)
50-
5137
env = os.environ.copy()
5238

5339
# El Capitan likes to unset dyld variables

0 commit comments

Comments
 (0)