@@ -172,6 +172,62 @@ fn parse_directives(path: &Path) -> Vec<String> {
172172 directives
173173}
174174
175+ fn parse_args ( args_str : & str ) -> Vec < & str > {
176+ let mut args = vec ! [ ] ;
177+
178+ let mut char_indices_iter = args_str. char_indices ( ) ;
179+ while let Some ( ( c_idx, c) ) = char_indices_iter. next ( ) {
180+ // NOTE: Skip past multiple consecutive whitespace separators between args.
181+ if c. is_whitespace ( ) { continue ; }
182+
183+ let ( start_idx, end_idx) = match c {
184+ '"' => {
185+ let start_idx = char_indices_iter. offset ( ) ;
186+ let end_idx = ' end_idx: {
187+ while let Some ( ( c_idx, c) ) = char_indices_iter. next ( ) {
188+ if c != '"' { continue ; }
189+ match char_indices_iter. clone ( ) . next ( ) {
190+ None => { break ' end_idx c_idx; }
191+ Some ( ( _, next_c) ) if next_c. is_whitespace ( ) => {
192+ // NOTE: Skip past the whitespace character after `"`.
193+ let _ = char_indices_iter. next ( ) ;
194+ break ' end_idx c_idx;
195+ }
196+ _ => { continue ; }
197+ }
198+ }
199+ // NOTE: This is the fallback value if `"` is not closed by the end of the args list.
200+ args_str. len ( )
201+ } ;
202+ ( start_idx, end_idx)
203+ }
204+ _ => {
205+ let end_idx = ' end_idx: {
206+ while let Some ( ( c_idx, c) ) = char_indices_iter. next ( ) {
207+ if c. is_whitespace ( ) { break ' end_idx c_idx; }
208+ }
209+ args_str. len ( )
210+ } ;
211+ ( c_idx, end_idx)
212+ }
213+ } ;
214+
215+ args. push ( & args_str[ start_idx..end_idx] ) ;
216+ }
217+
218+ args
219+ }
220+
221+ #[ test]
222+ fn test_parse_args ( ) {
223+ assert_eq ! ( [ "foo" , "bar" , "baz" ] , parse_args( "foo bar baz" ) [ ..] ) ;
224+ assert_eq ! ( [ "foo" , "bar" , "baz" ] , parse_args( "foo bar baz" ) [ ..] ) ;
225+ assert_eq ! ( [ "foo" , "bar baz" , "abc" ] , parse_args( "foo \" bar baz\" abc" ) [ ..] ) ;
226+ assert_eq ! ( [ "foo" , "bar=\" baz\" " , "abc" ] , parse_args( "foo \" bar=\" baz\" \" abc" ) [ ..] ) ;
227+ assert_eq ! ( [ "foo" , "bar baz" ] , parse_args( "foo \" bar baz\" " ) [ ..] ) ;
228+ assert_eq ! ( [ "foo" , "bar baz" ] , parse_args( "foo \" bar baz" ) [ ..] ) ;
229+ }
230+
175231fn run_test ( path : & Path , aux_dir_path : & Path , root_dir : & Path , opts : & Opts , results : & mut TestRunResults ) {
176232 if !path. is_file ( ) { return ; }
177233 if !path. extension ( ) . is_some_and ( |v| v == "rs" ) { return ; }
@@ -478,8 +534,7 @@ fn run_test(path: &Path, aux_dir_path: &Path, root_dir: &Path, opts: &Opts, resu
478534 cmd. env ( key, val) ;
479535 }
480536
481- let rustc_flags = directives. iter ( ) . filter_map ( |d| d. strip_prefix ( "rustc-flags:" ) . map ( str:: trim) )
482- . flat_map ( |flags| flags. split ( " " ) . filter ( |flag| !flag. is_empty ( ) ) ) ;
537+ let rustc_flags = directives. iter ( ) . filter_map ( |d| d. strip_prefix ( "rustc-flags:" ) . map ( str:: trim) ) . flat_map ( parse_args) ;
483538 cmd. args ( rustc_flags) ;
484539
485540 if aux {
@@ -506,7 +561,7 @@ fn run_test(path: &Path, aux_dir_path: &Path, root_dir: &Path, opts: &Opts, resu
506561 mutest_args. push ( mutest_prints. into_iter ( ) . intersperse ( "," ) . collect :: < String > ( ) ) ;
507562 }
508563 directives. iter ( ) . filter_map ( |d| d. strip_prefix ( "mutest-flags:" ) . map ( str:: trim) )
509- . flat_map ( |flags| flags . split ( " " ) . filter ( |flag| !flag . is_empty ( ) ) . map ( str:: to_owned) )
564+ . flat_map ( |flags| parse_args ( flags ) . into_iter ( ) . map ( str:: to_owned) )
510565 . collect_into ( & mut mutest_args) ;
511566 mutest_args. push ( mutest_subcommand. to_owned ( ) ) ;
512567 cmd. env ( "MUTEST_ENCODED_ARGS" . to_owned ( ) , mutest_args. join ( "\x1F " ) ) ;
@@ -561,8 +616,7 @@ fn run_test(path: &Path, aux_dir_path: &Path, root_dir: &Path, opts: &Opts, resu
561616 cmd. env ( key, val) ;
562617 }
563618
564- let run_flags = directives. iter ( ) . filter_map ( |d| d. strip_prefix ( "run-flags:" ) . map ( str:: trim) )
565- . flat_map ( |flags| flags. split ( " " ) . filter ( |flag| !flag. is_empty ( ) ) ) ;
619+ let run_flags = directives. iter ( ) . filter_map ( |d| d. strip_prefix ( "run-flags:" ) . map ( str:: trim) ) . flat_map ( parse_args) ;
566620 cmd. args ( run_flags) ;
567621
568622 // NOTE: Avoid passing on the `CARGO_*` environment variables from the test runner.
0 commit comments