@@ -210,9 +210,7 @@ top_level_options!(
210210/// generated code to parse an option into its respective field in the struct. There are a few
211211/// hand-written parsers for parsing specific types of values in this module.
212212macro_rules! options {
213- ( $struct_name: ident, $setter_name: ident, $defaultfn: ident,
214- $buildfn: ident, $prefix: expr, $outputname: expr,
215- $stat: ident,
213+ ( $struct_name: ident, $stat: ident, $prefix: expr, $outputname: expr,
216214 $( $( #[ $attr: meta] ) * $opt: ident : $t: ty = (
217215 $init: expr,
218216 $parse: ident,
@@ -223,50 +221,20 @@ macro_rules! options {
223221 #[ derive( Clone ) ]
224222 pub struct $struct_name { $( pub $opt: $t) ,* }
225223
226- pub fn $defaultfn( ) -> $struct_name {
227- $struct_name { $( $( #[ $attr] ) * $opt: $init) ,* }
228- }
229-
230- pub fn $buildfn( matches: & getopts:: Matches , error_format: ErrorOutputType ) -> $struct_name
231- {
232- let mut op = $defaultfn( ) ;
233- for option in matches. opt_strs( $prefix) {
234- let ( key, value) = match option. split_once( '=' ) {
235- None => ( option, None ) ,
236- Some ( ( k, v) ) => ( k. to_string( ) , Some ( v) ) ,
237- } ;
238- let option_to_lookup = key. replace( "-" , "_" ) ;
239- let mut found = false ;
240- for & ( candidate, setter, type_desc, _) in $stat {
241- if option_to_lookup != candidate { continue }
242- if !setter( & mut op, value) {
243- match value {
244- None => {
245- early_error( error_format, & format!( "{0} option `{1}` requires \
246- {2} ({3} {1}=<value>)",
247- $outputname, key,
248- type_desc, $prefix) )
249- }
250- Some ( value) => {
251- early_error( error_format, & format!( "incorrect value `{}` for {} \
252- option `{}` - {} was expected",
253- value, $outputname,
254- key, type_desc) )
255- }
256- }
257- }
258- found = true ;
259- break ;
260- }
261- if !found {
262- early_error( error_format, & format!( "unknown {} option: `{}`" ,
263- $outputname, key) ) ;
264- }
224+ impl Default for $struct_name {
225+ fn default ( ) -> $struct_name {
226+ $struct_name { $( $( #[ $attr] ) * $opt: $init) ,* }
265227 }
266- return op;
267228 }
268229
269230 impl $struct_name {
231+ pub fn build(
232+ matches: & getopts:: Matches ,
233+ error_format: ErrorOutputType ,
234+ ) -> $struct_name {
235+ build_options( matches, $stat, $prefix, $outputname, error_format)
236+ }
237+
270238 fn dep_tracking_hash( & self , _for_crate_hash: bool , error_format: ErrorOutputType ) -> u64 {
271239 let mut sub_hashes = BTreeMap :: new( ) ;
272240 $( {
@@ -284,26 +252,76 @@ macro_rules! options {
284252 }
285253 }
286254
287- pub type $setter_name = fn ( & mut $struct_name, v: Option <& str >) -> bool ;
288- pub const $stat: & [ ( & str , $setter_name, & str , & str ) ] =
289- & [ $( ( stringify!( $opt) , $crate:: options:: parse:: $opt, $crate:: options:: desc:: $parse, $desc) ) ,* ] ;
290-
291- // Sometimes different options need to build a common structure.
292- // That structure can kept in one of the options' fields, the others become dummy.
293- macro_rules! redirect_field {
294- ( $cg: ident. link_arg) => { $cg. link_args } ;
295- ( $cg: ident. pre_link_arg) => { $cg. pre_link_args } ;
296- ( $cg: ident. $field: ident) => { $cg. $field } ;
297- }
255+ pub const $stat: OptionDescrs <$struct_name> =
256+ & [ $( ( stringify!( $opt) , $opt, desc:: $parse, $desc) ) ,* ] ;
298257
299258 $(
300- pub fn $opt( cg: & mut $struct_name, v: Option <& str >) -> bool {
301- $crate :: options :: parse:: $parse( & mut redirect_field!( cg. $opt) , v)
259+ fn $opt( cg: & mut $struct_name, v: Option <& str >) -> bool {
260+ parse:: $parse( & mut redirect_field!( cg. $opt) , v)
302261 }
303262 ) *
304263
305264) }
306265
266+ // Sometimes different options need to build a common structure.
267+ // That structure can be kept in one of the options' fields, the others become dummy.
268+ macro_rules! redirect_field {
269+ ( $cg: ident. link_arg) => {
270+ $cg. link_args
271+ } ;
272+ ( $cg: ident. pre_link_arg) => {
273+ $cg. pre_link_args
274+ } ;
275+ ( $cg: ident. $field: ident) => {
276+ $cg. $field
277+ } ;
278+ }
279+
280+ type OptionSetter < O > = fn ( & mut O , v : Option < & str > ) -> bool ;
281+ type OptionDescrs < O > = & ' static [ ( & ' static str , OptionSetter < O > , & ' static str , & ' static str ) ] ;
282+
283+ fn build_options < O : Default > (
284+ matches : & getopts:: Matches ,
285+ descrs : OptionDescrs < O > ,
286+ prefix : & str ,
287+ outputname : & str ,
288+ error_format : ErrorOutputType ,
289+ ) -> O {
290+ let mut op = O :: default ( ) ;
291+ for option in matches. opt_strs ( prefix) {
292+ let ( key, value) = match option. split_once ( '=' ) {
293+ None => ( option, None ) ,
294+ Some ( ( k, v) ) => ( k. to_string ( ) , Some ( v) ) ,
295+ } ;
296+
297+ let option_to_lookup = key. replace ( "-" , "_" ) ;
298+ match descrs. iter ( ) . find ( |( name, ..) | * name == option_to_lookup) {
299+ Some ( ( _, setter, type_desc, _) ) => {
300+ if !setter ( & mut op, value) {
301+ match value {
302+ None => early_error (
303+ error_format,
304+ & format ! (
305+ "{0} option `{1}` requires {2} ({3} {1}=<value>)" ,
306+ outputname, key, type_desc, prefix
307+ ) ,
308+ ) ,
309+ Some ( value) => early_error (
310+ error_format,
311+ & format ! (
312+ "incorrect value `{}` for {} option `{}` - {} was expected" ,
313+ value, outputname, key, type_desc
314+ ) ,
315+ ) ,
316+ }
317+ }
318+ }
319+ None => early_error ( error_format, & format ! ( "unknown {} option: `{}`" , outputname, key) ) ,
320+ }
321+ }
322+ return op;
323+ }
324+
307325#[ allow( non_upper_case_globals) ]
308326mod desc {
309327 pub const parse_no_flag: & str = "no value" ;
@@ -847,9 +865,8 @@ mod parse {
847865 }
848866}
849867
850- options ! { CodegenOptions , CodegenSetter , basic_codegen_options,
851- build_codegen_options, "C" , "codegen" ,
852- CG_OPTIONS ,
868+ options ! {
869+ CodegenOptions , CG_OPTIONS , "C" , "codegen" ,
853870
854871 // This list is in alphabetical order.
855872 //
@@ -957,9 +974,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
957974 // - src/doc/rustc/src/codegen-options/index.md
958975}
959976
960- options ! { DebuggingOptions , DebuggingSetter , basic_debugging_options,
961- build_debugging_options, "Z" , "debugging" ,
962- DB_OPTIONS ,
977+ options ! {
978+ DebuggingOptions , DB_OPTIONS , "Z" , "debugging" ,
963979
964980 // This list is in alphabetical order.
965981 //
0 commit comments