@@ -6,248 +6,14 @@ extern crate env_logger;
6
6
#[ macro_use]
7
7
extern crate log;
8
8
extern crate clang_sys;
9
+ extern crate clap;
9
10
extern crate rustc_serialize;
10
11
11
- use bindgen:: { BindgenOptions , Bindings , LinkType , clang_version} ;
12
- use std:: default:: Default ;
12
+ use bindgen:: clang_version;
13
13
use std:: env;
14
- use std:: fs;
15
- use std:: io;
16
- use std:: path;
17
- use std:: process;
18
14
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;
251
17
252
18
pub fn main ( ) {
253
19
log:: set_logger ( |max_log_level| {
@@ -304,14 +70,18 @@ pub fn main() {
304
70
}
305
71
}
306
72
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) => {
83
+ println ! ( "{}" , error) ;
84
+ std:: process:: exit ( 1 ) ;
85
+ }
86
+ } ;
317
87
}
0 commit comments