@@ -98,33 +98,31 @@ fn is_flag(arg: &OsStr, options: &mut Options) -> bool {
9898/// # Returns
9999///
100100/// - Vector of non-flag arguments.
101- /// - [`Options`], describing how teh arguments should be interpreted.
102- fn filter_flags ( mut args : impl Iterator < Item = OsString > ) -> ( Vec < OsString > , Options ) {
103- let mut arguments = Vec :: with_capacity ( args. size_hint ( ) . 0 ) ;
101+ /// - [`Options`], describing how the arguments should be interpreted.
102+ fn filter_flags ( args : impl Iterator < Item = OsString > ) -> ( impl Iterator < Item = OsString > , Options ) {
104103 let mut options = Options :: default ( ) ;
104+ let mut args = args. peekable ( ) ;
105105
106106 // Process arguments until first non-flag is found.
107- for arg in & mut args {
107+ while let Some ( arg) = args. peek ( ) {
108108 // We parse flags and aggregate the options in `options`.
109- // First call to `is_echo_flag` to return false will break the loop.
110- if !is_flag ( & arg, & mut options) {
109+ // First call to `is_flag` to return false will break the loop.
110+ if is_flag ( arg, & mut options) {
111+ args. next ( ) ;
112+ } else {
111113 // Not a flag. Can break out of flag-processing loop.
112- // Don't forget to push it to the arguments too.
113- arguments. push ( arg) ;
114114 break ;
115115 }
116116 }
117117
118- // Collect remaining non-flag arguments.
119- arguments. extend ( args) ;
120-
121- ( arguments, options)
118+ // Return remaining non-flag arguments.
119+ ( args, options)
122120}
123121
124122#[ uucore:: main]
125123pub fn uumain ( args : impl uucore:: Args ) -> UResult < ( ) > {
126124 // args[0] is the name of the binary.
127- let args: Vec < OsString > = args. skip ( 1 ) . collect ( ) ;
125+ let mut args = args. skip ( 1 ) . peekable ( ) ;
128126
129127 // Check POSIX compatibility mode
130128 //
@@ -139,13 +137,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
139137 // > representation. For example, echo -e '\x2dn'.
140138 let is_posixly_correct = env:: var_os ( "POSIXLY_CORRECT" ) . is_some ( ) ;
141139
142- let ( args, options) = if is_posixly_correct {
143- if args. first ( ) . is_some_and ( |arg| arg == "-n" ) {
140+ let ( args, options) : ( Box < dyn Iterator < Item = OsString > > , Options ) = if is_posixly_correct {
141+ if args. peek ( ) . is_some_and ( |arg| arg == "-n" ) {
144142 // if POSIXLY_CORRECT is set and the first argument is the "-n" flag
145143 // we filter flags normally but 'escaped' is activated nonetheless.
146- let ( args, _) = filter_flags ( args. into_iter ( ) ) ;
144+ let ( args, _) = filter_flags ( args) ;
147145 (
148- args,
146+ Box :: new ( args) ,
149147 Options {
150148 trailing_newline : false ,
151149 ..Options :: posixly_correct_default ( )
@@ -154,24 +152,29 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
154152 } else {
155153 // if POSIXLY_CORRECT is set and the first argument is not the "-n" flag
156154 // we just collect all arguments as no arguments are interpreted as flags.
157- ( args, Options :: posixly_correct_default ( ) )
155+ ( Box :: new ( args) , Options :: posixly_correct_default ( ) )
158156 }
159- } else if args. len ( ) == 1 && args[ 0 ] == "--help" {
160- // If POSIXLY_CORRECT is not set and the first argument
161- // is `--help`, GNU coreutils prints the help message.
162- //
163- // Verify this using:
164- //
165- // POSIXLY_CORRECT=1 echo --help
166- // echo --help
167- uu_app ( ) . print_help ( ) ?;
168- return Ok ( ( ) ) ;
169- } else if args. len ( ) == 1 && args[ 0 ] == "--version" {
170- print ! ( "{}" , uu_app( ) . render_version( ) ) ;
171- return Ok ( ( ) ) ;
172- } else {
157+ } else if let Some ( first_arg) = args. next ( ) {
158+ if first_arg == "--help" && args. peek ( ) . is_none ( ) {
159+ // If POSIXLY_CORRECT is not set and the first argument
160+ // is `--help`, GNU coreutils prints the help message.
161+ //
162+ // Verify this using:
163+ //
164+ // POSIXLY_CORRECT=1 echo --help
165+ // echo --help
166+ uu_app ( ) . print_help ( ) ?;
167+ return Ok ( ( ) ) ;
168+ } else if first_arg == "--version" && args. peek ( ) . is_none ( ) {
169+ print ! ( "{}" , uu_app( ) . render_version( ) ) ;
170+ return Ok ( ( ) ) ;
171+ }
172+
173173 // if POSIXLY_CORRECT is not set we filter the flags normally
174- filter_flags ( args. into_iter ( ) )
174+ let ( args, options) = filter_flags ( std:: iter:: once ( first_arg) . chain ( args) ) ;
175+ ( Box :: new ( args) , options)
176+ } else {
177+ ( Box :: new ( args) , Options :: default ( ) )
175178 } ;
176179
177180 execute ( & mut io:: stdout ( ) . lock ( ) , args, options) ?;
@@ -221,7 +224,11 @@ pub fn uu_app() -> Command {
221224 )
222225}
223226
224- fn execute ( stdout : & mut StdoutLock , args : Vec < OsString > , options : Options ) -> UResult < ( ) > {
227+ fn execute (
228+ stdout : & mut StdoutLock ,
229+ args : impl Iterator < Item = OsString > ,
230+ options : Options ,
231+ ) -> UResult < ( ) > {
225232 for ( i, arg) in args. into_iter ( ) . enumerate ( ) {
226233 let bytes = os_str_as_bytes ( & arg) ?;
227234
0 commit comments