@@ -61,21 +61,16 @@ fn xargs_collect_args(
6161 args.push("echo".into());
6262 }
6363
64- if let Some(delim) = &flags.delimiter {
65- // strip a single trailing newline (xargs seems to do this)
66- let text = if *delim == '\n' {
67- if let Some(text) = text.strip_suffix(&delim.to_string()) {
68- text
69- } else {
70- &text
71- }
72- } else {
73- &text
74- };
64+ if flags.delimiter.is_some() || flags.is_null_delimited {
65+ let delimiter = flags.delimiter.unwrap_or('\0');
66+ args.extend(text.split(delimiter).map(|t| t.into()));
7567
76- args.extend(text.split(*delim).map(|t| t.into()));
77- } else if flags.is_null_delimited {
78- args.extend(text.split('\0').map(|t| t.into()));
68+ // remove last arg if it is empty
69+ if let Some(last) = args.last() {
70+ if last.is_empty() {
71+ args.pop();
72+ }
73+ }
7974 } else {
8075 args.extend(delimit_blanks(&text)?);
8176 }
@@ -315,4 +310,44 @@ mod test {
315310 "unmatched quote; by default quotes are special to xargs unless you use the -0 option",
316311 );
317312 }
313+
314+ #[test]
315+ fn test_xargs_collect_args() {
316+ fn collect(cli_args: &[&str], input: &str) -> Vec<String> {
317+ let stdin = ShellPipeReader::from_str(input);
318+ let cli_args = cli_args.iter().map(|s| s.into()).collect::<Vec<_>>();
319+ let result = xargs_collect_args(&cli_args, stdin).unwrap();
320+ result
321+ .into_iter()
322+ .map(|s| s.to_str().unwrap().to_string())
323+ .collect()
324+ }
325+
326+ // Test default behavior
327+ let result = collect(&[], "arg1 arg2\narg3");
328+ assert_eq!(result, ["echo", "arg1", "arg2", "arg3"]);
329+
330+ let result = collect(&[], "arg1 arg2\narg3\n");
331+ assert_eq!(result, ["echo", "arg1", "arg2", "arg3"]);
332+
333+ // printf "arg1 arg2\narg3\n\n" | xargs
334+ // > arg1 arg2 arg3
335+ let result = collect(&[], "arg1 arg2\n\narg3\n\n\n");
336+ assert_eq!(result, ["echo", "arg1", "arg2", "arg3"]);
337+
338+ // Test null-delimited with trailing null
339+ let result = collect(&["-0"], "arg1\0arg2\0arg3\0");
340+ assert_eq!(result, ["echo", "arg1", "arg2", "arg3"]);
341+
342+ // Test null-delimited with multiple nulls (all ignored)
343+ let result = collect(&["-0"], "arg1\0\0arg2\0arg3\0\0");
344+ assert_eq!(result, ["echo", "arg1", "", "arg2", "arg3", ""]);
345+
346+ // Test custom delimiter with trailing delimiter
347+ let result = collect(&["-d", ":"], "arg1:arg2:arg3:");
348+ assert_eq!(result, ["echo", "arg1", "arg2", "arg3"]);
349+
350+ let result = collect(&["-d", ":"], "arg1::arg2:arg3::");
351+ assert_eq!(result, ["echo", "arg1", "", "arg2", "arg3", ""]);
352+ }
318353}
0 commit comments