@@ -130,7 +130,7 @@ pub enum VerificationResult {
130130 NoOutput ,
131131}
132132
133- #[ derive( Debug , Default ) ]
133+ #[ derive( Debug ) ]
134134pub struct Settings {
135135 pub follow : Option < FollowMode > ,
136136 pub max_unchanged_stats : u32 ,
@@ -144,13 +144,26 @@ pub struct Settings {
144144 pub inputs : VecDeque < Input > ,
145145}
146146
147- impl Settings {
148- pub fn from_obsolete_args ( args : & parse:: ObsoleteArgs , name : Option < OsString > ) -> Self {
149- let mut settings: Self = Self {
150- sleep_sec : Duration :: from_secs_f32 ( 1.0 ) ,
147+ impl Default for Settings {
148+ fn default ( ) -> Self {
149+ Self {
151150 max_unchanged_stats : 5 ,
152- ..Default :: default ( )
153- } ;
151+ sleep_sec : Duration :: from_secs_f32 ( 1.0 ) ,
152+ follow : Default :: default ( ) ,
153+ mode : Default :: default ( ) ,
154+ pid : Default :: default ( ) ,
155+ retry : Default :: default ( ) ,
156+ use_polling : Default :: default ( ) ,
157+ verbose : Default :: default ( ) ,
158+ presume_input_pipe : Default :: default ( ) ,
159+ inputs : Default :: default ( ) ,
160+ }
161+ }
162+ }
163+
164+ impl Settings {
165+ pub fn from_obsolete_args ( args : & parse:: ObsoleteArgs , name : Option < & OsString > ) -> Self {
166+ let mut settings: Self = Default :: default ( ) ;
154167 if args. follow {
155168 settings. follow = if name. is_some ( ) {
156169 Some ( FollowMode :: Name )
@@ -170,25 +183,25 @@ impl Settings {
170183
171184 pub fn from ( matches : & clap:: ArgMatches ) -> UResult < Self > {
172185 let mut settings: Self = Self {
173- sleep_sec : Duration :: from_secs_f32 ( 1.0 ) ,
174- max_unchanged_stats : 5 ,
186+ follow : if matches. get_flag ( options:: FOLLOW_RETRY ) {
187+ Some ( FollowMode :: Name )
188+ } else if matches. value_source ( options:: FOLLOW ) != Some ( ValueSource :: CommandLine ) {
189+ None
190+ } else if matches. get_one :: < String > ( options:: FOLLOW )
191+ == Some ( String :: from ( "name" ) ) . as_ref ( )
192+ {
193+ Some ( FollowMode :: Name )
194+ } else {
195+ Some ( FollowMode :: Descriptor )
196+ } ,
197+ retry : matches. get_flag ( options:: RETRY ) || matches. get_flag ( options:: FOLLOW_RETRY ) ,
198+ use_polling : matches. get_flag ( options:: USE_POLLING ) ,
199+ mode : FilterMode :: from ( matches) ?,
200+ verbose : matches. get_flag ( options:: verbosity:: VERBOSE ) ,
201+ presume_input_pipe : matches. get_flag ( options:: PRESUME_INPUT_PIPE ) ,
175202 ..Default :: default ( )
176203 } ;
177204
178- settings. follow = if matches. get_flag ( options:: FOLLOW_RETRY ) {
179- Some ( FollowMode :: Name )
180- } else if matches. value_source ( options:: FOLLOW ) != Some ( ValueSource :: CommandLine ) {
181- None
182- } else if matches. get_one :: < String > ( options:: FOLLOW ) == Some ( String :: from ( "name" ) ) . as_ref ( )
183- {
184- Some ( FollowMode :: Name )
185- } else {
186- Some ( FollowMode :: Descriptor )
187- } ;
188-
189- settings. retry =
190- matches. get_flag ( options:: RETRY ) || matches. get_flag ( options:: FOLLOW_RETRY ) ;
191-
192205 if let Some ( source) = matches. get_one :: < String > ( options:: SLEEP_INT ) {
193206 // Advantage of `fundu` over `Duration::(try_)from_secs_f64(source.parse().unwrap())`:
194207 // * doesn't panic on errors like `Duration::from_secs_f64` would.
@@ -205,8 +218,6 @@ impl Settings {
205218 } ) ?;
206219 }
207220
208- settings. use_polling = matches. get_flag ( options:: USE_POLLING ) ;
209-
210221 if let Some ( s) = matches. get_one :: < String > ( options:: MAX_UNCHANGED_STATS ) {
211222 settings. max_unchanged_stats = match s. parse :: < u32 > ( ) {
212223 Ok ( s) => s,
@@ -246,8 +257,6 @@ impl Settings {
246257 }
247258 }
248259
249- settings. mode = FilterMode :: from ( matches) ?;
250-
251260 let mut inputs: VecDeque < Input > = matches
252261 . get_many :: < String > ( options:: ARG_FILES )
253262 . map ( |v| v. map ( |string| Input :: from ( & string) ) . collect ( ) )
@@ -258,13 +267,10 @@ impl Settings {
258267 inputs. push_front ( Input :: default ( ) ) ;
259268 }
260269
261- settings. verbose = ( matches. get_flag ( options:: verbosity:: VERBOSE ) || inputs. len ( ) > 1 )
262- && !matches. get_flag ( options:: verbosity:: QUIET ) ;
270+ settings. verbose = inputs. len ( ) > 1 && !matches. get_flag ( options:: verbosity:: QUIET ) ;
263271
264272 settings. inputs = inputs;
265273
266- settings. presume_input_pipe = matches. get_flag ( options:: PRESUME_INPUT_PIPE ) ;
267-
268274 Ok ( settings)
269275 }
270276
@@ -342,6 +348,19 @@ impl Settings {
342348
343349 VerificationResult :: Ok
344350 }
351+
352+ pub fn is_default ( & self ) -> bool {
353+ let default = Self :: default ( ) ;
354+ self . max_unchanged_stats == default. max_unchanged_stats
355+ && self . sleep_sec == default. sleep_sec
356+ && self . follow == default. follow
357+ && self . mode == default. mode
358+ && self . pid == default. pid
359+ && self . retry == default. retry
360+ && self . use_polling == default. use_polling
361+ && ( self . verbose == default. verbose || self . inputs . len ( ) > 1 )
362+ && self . presume_input_pipe == default. presume_input_pipe
363+ }
345364}
346365
347366pub fn parse_obsolete ( args : & str ) -> UResult < Option < parse:: ObsoleteArgs > > {
@@ -389,28 +408,42 @@ fn parse_num(src: &str) -> Result<Signum, ParseSizeError> {
389408 } )
390409}
391410
392- pub fn parse_args ( mut args : impl uucore:: Args ) -> UResult < Settings > {
393- let first = args. next ( ) . unwrap ( ) ;
394- let second = match args. next ( ) {
411+ pub fn parse_args ( args : impl uucore:: Args ) -> UResult < Settings > {
412+ let args_vec: Vec < OsString > = args. collect ( ) ;
413+ let clap_result = match uu_app ( ) . try_get_matches_from ( args_vec. clone ( ) ) {
414+ Ok ( matches) => {
415+ let settings = Settings :: from ( & matches) ?;
416+ if !settings. is_default ( ) {
417+ // non-default settings can't have obsolete arguments
418+ return Ok ( settings) ;
419+ }
420+ Ok ( settings)
421+ }
422+ Err ( err) => Err ( err. into ( ) ) ,
423+ } ;
424+
425+ // clap parsing failed or resulted to default -> check for obsolete/deprecated args
426+ // argv[0] is always present
427+ let second = match args_vec. get ( 1 ) {
395428 Some ( second) => second,
396- None => return Settings :: from ( & uu_app ( ) . try_get_matches_from ( vec ! [ first ] ) ? ) ,
429+ None => return clap_result ,
397430 } ;
398431 let second_str = match second. to_str ( ) {
399432 Some ( second_str) => second_str,
400433 None => {
401- let second_string = second. to_string_lossy ( ) ;
434+ let invalid_string = second. to_string_lossy ( ) ;
402435 return Err ( USimpleError :: new (
403436 1 ,
404- format ! ( "bad argument encoding: '{second_string }'" ) ,
437+ format ! ( "bad argument encoding: '{invalid_string }'" ) ,
405438 ) ) ;
406439 }
407440 } ;
408441 match parse_obsolete ( second_str) ? {
409- Some ( obsolete_args) => Ok ( Settings :: from_obsolete_args ( & obsolete_args , args . next ( ) ) ) ,
410- None => {
411- let args = vec ! [ first , second ] . into_iter ( ) . chain ( args ) ;
412- Settings :: from ( & uu_app ( ) . try_get_matches_from ( args ) ? )
413- }
442+ Some ( obsolete_args) => Ok ( Settings :: from_obsolete_args (
443+ & obsolete_args ,
444+ args_vec . get ( 2 ) ,
445+ ) ) ,
446+ None => clap_result ,
414447 }
415448}
416449
@@ -583,7 +616,7 @@ mod tests {
583616 let result = Settings :: from_obsolete_args ( & args, None ) ;
584617 assert_eq ! ( result. follow, Some ( FollowMode :: Descriptor ) ) ;
585618
586- let result = Settings :: from_obsolete_args ( & args, Some ( "test ". into ( ) ) ) ;
619+ let result = Settings :: from_obsolete_args ( & args, Some ( & "file ". into ( ) ) ) ;
587620 assert_eq ! ( result. follow, Some ( FollowMode :: Name ) ) ;
588621 }
589622}
0 commit comments