1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #2151 from jfinkels/2141-translate-and-squeeze

tr: implement translate and squeeze (-s) mode
This commit is contained in:
Sylvestre Ledru 2021-05-01 23:27:43 +02:00 committed by GitHub
commit 7e07438b38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 3 deletions

View file

@ -149,6 +149,35 @@ impl SymbolTranslator for TranslateOperation {
}
}
struct TranslateAndSqueezeOperation {
translate: TranslateOperation,
squeeze: SqueezeOperation,
}
impl TranslateAndSqueezeOperation {
fn new(
set1: ExpandSet,
set2: &mut ExpandSet,
set2_: ExpandSet,
truncate: bool,
complement: bool,
) -> TranslateAndSqueezeOperation {
TranslateAndSqueezeOperation {
translate: TranslateOperation::new(set1, set2, truncate),
squeeze: SqueezeOperation::new(set2_, complement),
}
}
}
impl SymbolTranslator for TranslateAndSqueezeOperation {
fn translate(&self, c: char, prev_c: char) -> Option<char> {
// `unwrap()` will never panic because `Translate.translate()`
// always returns `Some`.
self.squeeze
.translate(self.translate.translate(c, 0 as char).unwrap(), prev_c)
}
}
fn translate_input<T: SymbolTranslator>(
input: &mut dyn BufRead,
output: &mut dyn Write,
@ -166,8 +195,11 @@ fn translate_input<T: SymbolTranslator>(
// isolation to make borrow checker happy
let filtered = buf.chars().filter_map(|c| {
let res = translator.translate(c, prev_c);
// Set `prev_c` to the post-translate character. This
// allows the squeeze operation to correctly function
// after the translate operation.
if res.is_some() {
prev_c = c;
prev_c = res.unwrap();
}
res
});
@ -290,8 +322,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
}
} else if squeeze_flag {
let op = SqueezeOperation::new(set1, complement_flag);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
if sets.len() < 2 {
let op = SqueezeOperation::new(set1, complement_flag);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
} else {
let mut set2 = ExpandSet::new(sets[1].as_ref());
let set2_ = ExpandSet::new(sets[1].as_ref());
let op = TranslateAndSqueezeOperation::new(
set1,
&mut set2,
set2_,
complement_flag,
truncate_flag,
);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
}
} else {
let mut set2 = ExpandSet::new(sets[1].as_ref());
let op = TranslateOperation::new(set1, &mut set2, truncate_flag);

View file

@ -77,6 +77,24 @@ fn test_squeeze_complement() {
.stdout_is("aaBcDcc");
}
#[test]
fn test_translate_and_squeeze() {
new_ucmd!()
.args(&["-s", "x", "y"])
.pipe_in("xx")
.run()
.stdout_is("y");
}
#[test]
fn test_translate_and_squeeze_multiple_lines() {
new_ucmd!()
.args(&["-s", "x", "y"])
.pipe_in("xxaax\nxaaxx")
.run()
.stdout_is("yaay\nyaay");
}
#[test]
fn test_delete_and_squeeze() {
new_ucmd!()