@@ -11,6 +11,7 @@ use std::io::{self, StdoutLock, Write};
1111use uucore:: error:: { UResult , USimpleError } ;
1212use uucore:: format:: { FormatChar , OctalParsing , parse_escape_only} ;
1313use uucore:: format_usage;
14+ use uucore:: os_str_as_bytes;
1415
1516use uucore:: locale:: get_message;
1617
@@ -99,7 +100,7 @@ fn is_flag(arg: &OsStr, options: &mut Options) -> bool {
99100///
100101/// - Vector of non-flag arguments.
101102/// - [`Options`], describing how teh arguments should be interpreted.
102- fn filter_flags ( mut args : impl uucore :: Args ) -> ( Vec < OsString > , Options ) {
103+ fn filter_flags ( mut args : impl Iterator < Item = OsString > ) -> ( Vec < OsString > , Options ) {
103104 let mut arguments = Vec :: with_capacity ( args. size_hint ( ) . 0 ) ;
104105 let mut options = Options :: default ( ) ;
105106
@@ -124,7 +125,7 @@ fn filter_flags(mut args: impl uucore::Args) -> (Vec<OsString>, Options) {
124125#[ uucore:: main]
125126pub fn uumain ( args : impl uucore:: Args ) -> UResult < ( ) > {
126127 // args[0] is the name of the binary.
127- let mut args = args. skip ( 1 ) . peekable ( ) ;
128+ let args: Vec < OsString > = args. skip ( 1 ) . collect ( ) ;
128129
129130 // Check POSIX compatibility mode
130131 //
@@ -139,28 +140,36 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
139140 // > representation. For example, echo -e '\x2dn'.
140141 let is_posixly_correct = env:: var_os ( "POSIXLY_CORRECT" ) . is_some ( ) ;
141142
142- let ( args, options) = match is_posixly_correct {
143- // if POSIXLY_CORRECT is not set we filter the flags normally
144- false => filter_flags ( args) ,
145-
146- true if args. peek ( ) . is_some_and ( |arg| arg == "-n" ) => {
143+ let ( args, options) = if is_posixly_correct {
144+ if args. first ( ) . is_some_and ( |arg| arg == "-n" ) {
147145 // if POSIXLY_CORRECT is set and the first argument is the "-n" flag
148146 // we filter flags normally but 'escaped' is activated nonetheless.
149- let ( args, _) = filter_flags ( args) ;
147+ let ( args, _) = filter_flags ( args. into_iter ( ) ) ;
150148 (
151149 args,
152150 Options {
153151 trailing_newline : false ,
154152 ..Options :: posixly_correct_default ( )
155153 } ,
156154 )
157- }
158-
159- true => {
155+ } else {
160156 // if POSIXLY_CORRECT is set and the first argument is not the "-n" flag
161- // we just collect all arguments as every argument is considered an argument .
162- ( args. collect ( ) , Options :: posixly_correct_default ( ) )
157+ // we just collect all arguments as no arguments are interpreted as flags .
158+ ( args, Options :: posixly_correct_default ( ) )
163159 }
160+ } else if args. len ( ) == 1 && args[ 0 ] == "--help" {
161+ // If POSIXLY_CORRECT is not set and the first argument
162+ // is `--help`, GNU coreutils prints the help message.
163+ //
164+ // Verify this using:
165+ //
166+ // POSIXLY_CORRECT=1 echo --help
167+ // echo --help
168+ uu_app ( ) . print_help ( ) ?;
169+ return Ok ( ( ) ) ;
170+ } else {
171+ // if POSIXLY_CORRECT is not set we filter the flags normally
172+ filter_flags ( args. into_iter ( ) )
164173 } ;
165174
166175 execute ( & mut io:: stdout ( ) . lock ( ) , args, options) ?;
@@ -211,9 +220,8 @@ pub fn uu_app() -> Command {
211220
212221fn execute ( stdout : & mut StdoutLock , args : Vec < OsString > , options : Options ) -> UResult < ( ) > {
213222 for ( i, arg) in args. into_iter ( ) . enumerate ( ) {
214- let Some ( bytes) = bytes_from_os_string ( arg. as_os_str ( ) ) else {
215- return Err ( USimpleError :: new ( 1 , get_message ( "echo-error-non-utf8" ) ) ) ;
216- } ;
223+ let bytes = os_str_as_bytes ( arg. as_os_str ( ) )
224+ . map_err ( |_| USimpleError :: new ( 1 , get_message ( "echo-error-non-utf8" ) ) ) ?;
217225
218226 if i > 0 {
219227 stdout. write_all ( b" " ) ?;
@@ -236,18 +244,3 @@ fn execute(stdout: &mut StdoutLock, args: Vec<OsString>, options: Options) -> UR
236244
237245 Ok ( ( ) )
238246}
239-
240- fn bytes_from_os_string ( input : & OsStr ) -> Option < & [ u8 ] > {
241- #[ cfg( target_family = "unix" ) ]
242- {
243- use std:: os:: unix:: ffi:: OsStrExt ;
244-
245- Some ( input. as_bytes ( ) )
246- }
247-
248- #[ cfg( not( target_family = "unix" ) ) ]
249- {
250- // TODO: Verify that this works correctly on these platforms
251- input. to_str ( ) . map ( |st| st. as_bytes ( ) )
252- }
253- }
0 commit comments