mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
Merge pull request #4260 from sbentmar/expand-fix-perl-failures
expand: improve plus specifier handling
This commit is contained in:
commit
efc70ade68
2 changed files with 106 additions and 14 deletions
|
@ -126,12 +126,8 @@ fn tabstops_parse(s: &str) -> Result<(RemainingMode, Vec<usize>), ParseError> {
|
||||||
let bytes = word.as_bytes();
|
let bytes = word.as_bytes();
|
||||||
for i in 0..bytes.len() {
|
for i in 0..bytes.len() {
|
||||||
match bytes[i] {
|
match bytes[i] {
|
||||||
b'+' => {
|
b'+' => remaining_mode = RemainingMode::Plus,
|
||||||
remaining_mode = RemainingMode::Plus;
|
b'/' => remaining_mode = RemainingMode::Slash,
|
||||||
}
|
|
||||||
b'/' => {
|
|
||||||
remaining_mode = RemainingMode::Slash;
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
// Parse a number from the byte sequence.
|
// Parse a number from the byte sequence.
|
||||||
let s = from_utf8(&bytes[i..]).unwrap();
|
let s = from_utf8(&bytes[i..]).unwrap();
|
||||||
|
@ -191,6 +187,10 @@ fn tabstops_parse(s: &str) -> Result<(RemainingMode, Vec<usize>), ParseError> {
|
||||||
if nums.is_empty() {
|
if nums.is_empty() {
|
||||||
nums = vec![DEFAULT_TABSTOP];
|
nums = vec![DEFAULT_TABSTOP];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nums.len() < 2 {
|
||||||
|
remaining_mode = RemainingMode::None;
|
||||||
|
}
|
||||||
Ok((remaining_mode, nums))
|
Ok((remaining_mode, nums))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,17 +336,19 @@ fn open(path: &str) -> BufReader<Box<dyn Read + 'static>> {
|
||||||
/// in the `tabstops` slice is interpreted as a relative number of
|
/// in the `tabstops` slice is interpreted as a relative number of
|
||||||
/// spaces, which this function will return for every input value of
|
/// spaces, which this function will return for every input value of
|
||||||
/// `col` beyond the end of the second-to-last element of `tabstops`.
|
/// `col` beyond the end of the second-to-last element of `tabstops`.
|
||||||
///
|
|
||||||
/// If `remaining_mode` is [`RemainingMode::Plus`], then the last entry
|
|
||||||
/// in the `tabstops` slice is interpreted as a relative number of
|
|
||||||
/// spaces, which this function will return for every input value of
|
|
||||||
/// `col` beyond the end of the second-to-last element of `tabstops`.
|
|
||||||
fn next_tabstop(tabstops: &[usize], col: usize, remaining_mode: &RemainingMode) -> usize {
|
fn next_tabstop(tabstops: &[usize], col: usize, remaining_mode: &RemainingMode) -> usize {
|
||||||
let num_tabstops = tabstops.len();
|
let num_tabstops = tabstops.len();
|
||||||
match remaining_mode {
|
match remaining_mode {
|
||||||
RemainingMode::Plus => match tabstops[0..num_tabstops - 1].iter().find(|&&t| t > col) {
|
RemainingMode::Plus => match tabstops[0..num_tabstops - 1].iter().find(|&&t| t > col) {
|
||||||
Some(t) => t - col,
|
Some(t) => t - col,
|
||||||
None => tabstops[num_tabstops - 1] - 1,
|
None => {
|
||||||
|
let step_size = tabstops[num_tabstops - 1];
|
||||||
|
let last_fixed_tabstop = tabstops[num_tabstops - 2];
|
||||||
|
let characters_since_last_tabstop = col - last_fixed_tabstop;
|
||||||
|
|
||||||
|
let steps_required = 1 + characters_since_last_tabstop / step_size;
|
||||||
|
steps_required * step_size - characters_since_last_tabstop
|
||||||
|
}
|
||||||
},
|
},
|
||||||
RemainingMode::Slash => match tabstops[0..num_tabstops - 1].iter().find(|&&t| t > col) {
|
RemainingMode::Slash => match tabstops[0..num_tabstops - 1].iter().find(|&&t| t > col) {
|
||||||
Some(t) => t - col,
|
Some(t) => t - col,
|
||||||
|
@ -487,8 +489,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_next_tabstop_remaining_mode_plus() {
|
fn test_next_tabstop_remaining_mode_plus() {
|
||||||
assert_eq!(next_tabstop(&[1, 5], 0, &RemainingMode::Plus), 1);
|
assert_eq!(next_tabstop(&[1, 5], 0, &RemainingMode::Plus), 1);
|
||||||
assert_eq!(next_tabstop(&[1, 5], 3, &RemainingMode::Plus), 4);
|
assert_eq!(next_tabstop(&[1, 5], 3, &RemainingMode::Plus), 3);
|
||||||
assert_eq!(next_tabstop(&[1, 5], 6, &RemainingMode::Plus), 4);
|
assert_eq!(next_tabstop(&[1, 5], 6, &RemainingMode::Plus), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -298,3 +298,93 @@ fn test_tabs_and_tabs_shortcut_mixed() {
|
||||||
// 01234567890
|
// 01234567890
|
||||||
.stdout_is(" a b c");
|
.stdout_is(" a b c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ignore_initial_plus() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=+3"])
|
||||||
|
.pipe_in("\ta\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ignore_initial_pluses() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=++3"])
|
||||||
|
.pipe_in("\ta\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ignore_initial_slash() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=/3"])
|
||||||
|
.pipe_in("\ta\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ignore_initial_slashes() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=//3"])
|
||||||
|
.pipe_in("\ta\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ignore_initial_plus_slash_combination() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=+/3"])
|
||||||
|
.pipe_in("\ta\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comma_with_plus_1() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=3,+6"])
|
||||||
|
.pipe_in("\t111\t222\t333")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" 111 222 333");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comma_with_plus_2() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=1,+5"])
|
||||||
|
.pipe_in("\ta\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is(" a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comma_with_plus_3() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=2,+5"])
|
||||||
|
.pipe_in("a\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is("a b c");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comma_with_plus_4() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["--tabs=1,3,+5"])
|
||||||
|
.pipe_in("a\tb\tc")
|
||||||
|
.succeeds()
|
||||||
|
// 01234567890
|
||||||
|
.stdout_is("a b c");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue