diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 2ca0e8eae87..1840f659c38 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -303,8 +303,8 @@ fn next_tabstop(tab_config: &TabConfig, col: usize) -> Option { } if tabstops.len() == 1 - && tab_config.increment_size.is_none() - && tab_config.extend_size.is_none() + && !matches!(tab_config.increment_size, Some(n) if n > 0) + && !matches!(tab_config.extend_size, Some(n) if n > 0) { // Simple case: single tab stop, repeat at that interval Some(tabstops[0] - col % tabstops[0]) diff --git a/tests/by-util/test_unexpand.rs b/tests/by-util/test_unexpand.rs index 1029d67e602..fdba510c300 100644 --- a/tests/by-util/test_unexpand.rs +++ b/tests/by-util/test_unexpand.rs @@ -329,3 +329,31 @@ fn test_blanks_ext2() { .succeeds() .stdout_is("\t\t"); } + +#[test] +fn test_extended_tabstop_syntax() { + let test_cases = [ + // Standalone /N: tabs at multiples of N + ("-t /9", " ", "\t"), // 9 spaces -> 1 tab + ("-t /9", " ", "\t\t"), // 18 spaces -> 2 tabs + // Standalone +N: tabs at multiples of N + ("-t +6", " ", "\t"), // 6 spaces -> 1 tab + ("-t +6", " ", "\t\t"), // 12 spaces -> 2 tabs + // 3,/0 and 3,+0 should behave like just 3 + ("-t 3,/0", " ", "\t\t\t "), // 10 spaces -> 3 tabs + 1 space + ("-t 3,+0", " ", "\t\t\t "), // 10 spaces -> 3 tabs + 1 space + ("-t 3", " ", "\t\t\t "), // 10 spaces -> 3 tabs + 1 space + // 3,/0 with text + ("-t 3,/0", " test", "\ttest"), // 3 spaces + text -> 1 tab + text + // 3,+6 means tab stops at 3, 9, 15, 21, ... + ("-t 3,+6", " ", "\t\t\t "), // 20 spaces -> 3 tabs + 5 spaces + ]; + + for (args, input, expected) in test_cases { + new_ucmd!() + .args(&args.split_whitespace().collect::>()) + .pipe_in(input) + .succeeds() + .stdout_is(expected); + } +}