@@ -6,248 +6,14 @@ extern crate env_logger;
66#[ macro_use]
77extern crate log;
88extern crate clang_sys;
9+ extern crate clap;
910extern crate rustc_serialize;
1011
11- use bindgen:: { BindgenOptions , Bindings , LinkType , clang_version} ;
12- use std:: default:: Default ;
12+ use bindgen:: clang_version;
1313use std:: env;
14- use std:: fs;
15- use std:: io;
16- use std:: path;
17- use std:: process;
1814
19- const USAGE : & ' static str = "
20- Usage:
21- bindgen [options] \
22- [--link=<lib>...] \
23- [--static-link=<lib>...] \
24- [--framework-link=<framework>...] \
25- [--raw-line=<raw>...] \
26- [--opaque-type=<type>...] \
27- [--blacklist-type=<type>...] \
28- [--whitelist-type=<type>...] \
29- [--whitelist-function=<name>...] \
30- [--whitelist-var=<name>...] \
31- [--bitfield-enum=<name>...] \
32- <input-header> \
33- [-- <clang-args>...]
34-
35- bindgen (-h | --help)
36-
37- Options:
38- -h, --help Display this help message.
39-
40- -l=<lib>, --link=<lib> Link to a dynamic library, can be provided
41- multiple times.
42-
43- --static-link=<lib> Link to a static library, can be provided
44- multiple times.
45-
46- --framework-link=<framework> Link to a framework.
47-
48- -o=<output-rust-file> Write bindings to <output-rust-file>
49- (defaults to stdout)
50-
51- --builtins Output bindings for builtin definitions (for
52- example __builtin_va_list)
53-
54- --ignore-functions Don't generate bindings for functions and
55- methods. This is useful when you only care
56- about struct layouts.
57-
58- --ignore-methods Avoid generating all kind of methods.
59-
60- --enable-cxx-namespaces Enable support for C++ namespaces.
61-
62- --emit-clang-ast Output the ast (for debugging purposes)
63-
64- --use-msvc-mangling Handle MSVC C++ ABI mangling; requires that
65- target be set to (i686|x86_64)-pc-win32
66-
67- --no-convert-floats Don't convert floats automatically to f32/f64.
68-
69- --raw-line=<raw> Add a raw line at the beginning of the output.
70-
71- --no-unstable-rust Avoid generating unstable rust.
72-
73- --use-core Use built-in types from core instead of std.
74-
75- --ctypes-prefix=<prefix> Use the given prefix before the raw types
76- instead of ::std::os::raw::.
77-
78- --opaque-type=<type> Mark a type as opaque.
79-
80- --blacklist-type=<type> Mark a type as hidden.
81-
82- --whitelist-type=<type> Whitelist the type. If this set or any other
83- of the whitelisting sets is not empty, then
84- all the non-whitelisted types (or dependant)
85- won't be generated.
86-
87- --whitelist-function=<regex> Whitelist all the free-standing functions
88- matching <regex>. Same behavior on emptyness
89- than the type whitelisting.
90-
91- --whitelist-var=<regex> Whitelist all the free-standing variables
92- matching <regex>. Same behavior on emptyness
93- than the type whitelisting.
94-
95- --bitfield-enum=<regex> Mark any enum whose name matches <regex> as a
96- set of bitfield flags instead of an
97- enumeration.
98-
99- --dummy-uses=<path> For testing purposes, generate a C/C++ file
100- containing dummy uses of all types defined in
101- the input header.
102-
103- <clang-args> Options other than stated above are passed
104- directly through to clang.
105- " ;
106-
107- // FIXME(emilio): Replace this with docopt if/when they fix their exponential
108- // algorithm for argument parsing.
109- //
110- // FIXME(fitzgen): Switch from `BindgenOptions` to the non-deprecated `Builder`.
111- #[ allow( deprecated) ]
112- fn parse_args_or_exit ( args : Vec < String > ) -> ( BindgenOptions , Box < io:: Write > ) {
113- let mut options = BindgenOptions :: default ( ) ;
114- let mut dest_file = None ;
115- let mut source_file = None ;
116-
117- let mut iter = args. into_iter ( ) . skip ( 1 ) ;
118- loop {
119- let next = match iter. next ( ) {
120- Some ( arg) => arg,
121- _ => break ,
122- } ;
123-
124- match & * next {
125- "-h" | "--help" => {
126- println ! ( "{}" , USAGE ) ;
127- process:: exit ( 0 ) ;
128- }
129- "-l" | "--link" => {
130- let lib = iter. next ( ) . expect ( "--link needs an argument" ) ;
131- options. links . push ( ( lib, LinkType :: Default ) ) ;
132- }
133- "--static-link" => {
134- let lib = iter. next ( ) . expect ( "--static-link needs an argument" ) ;
135- options. links . push ( ( lib, LinkType :: Static ) ) ;
136- }
137- "--framework-link" => {
138- let lib = iter. next ( )
139- . expect ( "--framework-link needs an argument" ) ;
140- options. links . push ( ( lib, LinkType :: Framework ) ) ;
141- }
142- "--raw-line" => {
143- let line = iter. next ( ) . expect ( "--raw-line needs an argument" ) ;
144- options. raw_lines . push ( line) ;
145- }
146- "--opaque-type" => {
147- let ty_canonical_name = iter. next ( )
148- . expect ( "--opaque-type expects a type" ) ;
149- options. opaque_types . insert ( ty_canonical_name) ;
150- }
151- "--blacklist-type" => {
152- let ty_canonical_name = iter. next ( )
153- . expect ( "--blacklist-type expects a type" ) ;
154- options. hidden_types . insert ( ty_canonical_name) ;
155- }
156- "--whitelist-type" => {
157- let ty_pat = iter. next ( )
158- . expect ( "--whitelist-type expects a type pattern" ) ;
159- options. whitelisted_types . insert ( & ty_pat) ;
160- }
161- "--whitelist-function" => {
162- let function_pat = iter. next ( )
163- . expect ( "--whitelist-function expects a pattern" ) ;
164- options. whitelisted_functions . insert ( & function_pat) ;
165- }
166- "--whitelist-var" => {
167- let var_pat = iter. next ( )
168- . expect ( "--whitelist-var expects a pattern" ) ;
169- options. whitelisted_vars . insert ( & var_pat) ;
170- }
171- "--bitfield-enum" => {
172- let enum_pat = iter. next ( )
173- . expect ( "--bitfield-enum expects a pattern" ) ;
174- options. bitfield_enums . insert ( & enum_pat) ;
175- }
176- "--" => {
177- while let Some ( clang_arg) = iter. next ( ) {
178- options. clang_args . push ( clang_arg) ;
179- }
180- }
181- "--output" | "-o" => {
182- let out_name = iter. next ( ) . expect ( "-o expects a file name" ) ;
183- dest_file = Some ( out_name) ;
184- }
185- "--builtins" => {
186- options. builtins = true ;
187- }
188- "--ignore-functions" => {
189- options. ignore_functions = true ;
190- }
191- "--ignore-methods" => {
192- options. ignore_methods = true ;
193- }
194- "--enable-cxx-namespaces" => {
195- options. enable_cxx_namespaces = true ;
196- }
197- "--no-unstable-rust" => {
198- options. unstable_rust = false ;
199- }
200- "--use-core" => {
201- options. use_core = true ;
202- }
203- "--ctypes-prefix" => {
204- let prefix = iter. next ( )
205- . expect ( "--ctypes-prefix expects a prefix after it" ) ;
206- options. ctypes_prefix = Some ( prefix) ;
207- }
208- "--emit-clang-ast" => {
209- options. emit_ast = true ;
210- }
211- "--no-convert-floats" => {
212- options. convert_floats = false ;
213- }
214- "--use-msvc-mangling" => {
215- options. msvc_mangling = true ;
216- }
217- "--dummy-uses" => {
218- let dummy_path = iter. next ( )
219- . expect ( "--dummy-uses expects a file path" ) ;
220- options. dummy_uses = Some ( dummy_path) ;
221- }
222- other if source_file. is_none ( ) => {
223- source_file = Some ( other. into ( ) ) ;
224- }
225- other => {
226- panic ! ( "Unknown option: \" {}\" " , other) ;
227- }
228- }
229- }
230-
231- if let Some ( source_file) = source_file. take ( ) {
232- options. clang_args . push ( source_file) ;
233- options. input_header = options. clang_args . last ( ) . cloned ( ) ;
234- } else {
235- options. input_header = options. clang_args
236- . iter ( )
237- . find ( |arg| arg. ends_with ( ".h" ) || arg. ends_with ( ".hpp" ) )
238- . cloned ( ) ;
239- }
240-
241- let out = if let Some ( ref path_name) = dest_file {
242- let path = path:: Path :: new ( path_name) ;
243- let file = fs:: File :: create ( path) . expect ( "Opening out file failed" ) ;
244- Box :: new ( io:: BufWriter :: new ( file) ) as Box < io:: Write >
245- } else {
246- Box :: new ( io:: BufWriter :: new ( io:: stdout ( ) ) ) as Box < io:: Write >
247- } ;
248-
249- ( options, out)
250- }
15+ mod options;
16+ use options:: builder_from_flags;
25117
25218pub fn main ( ) {
25319 log:: set_logger ( |max_log_level| {
@@ -304,14 +70,15 @@ pub fn main() {
30470 }
30571 }
30672
307- let ( options, out) = parse_args_or_exit ( bind_args) ;
308-
309- let mut bindings = Bindings :: generate ( options, None )
310- . expect ( "Unable to generate bindings" ) ;
311-
312- bindings. write_dummy_uses ( )
313- . expect ( "Unable to write dummy uses to file." ) ;
314-
315- bindings. write ( out)
316- . expect ( "Unable to write bindings to file." ) ;
73+ match builder_from_flags ( env:: args ( ) ) {
74+ Ok ( ( builder, output) ) => {
75+ let mut bindings = builder. generate ( )
76+ . expect ( "Unable to generate bindings" ) ;
77+ bindings. write ( output)
78+ . expect ( "Unable to write output" ) ;
79+ bindings. write_dummy_uses ( )
80+ . expect ( "Unable to write dummy uses to file." ) ;
81+ }
82+ Err ( error) => println ! ( "{}" , error)
83+ } ;
31784}
0 commit comments