1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 03:57:44 +00:00

tr: implement complement separately from delete or squeeze (#2147)

This commit is contained in:
Jan Scheer 2021-05-01 18:46:13 +02:00
parent 247de489f5
commit 117e84eed3
2 changed files with 51 additions and 10 deletions

View file

@ -125,10 +125,17 @@ impl SymbolTranslator for DeleteAndSqueezeOperation {
struct TranslateOperation { struct TranslateOperation {
translate_map: FnvHashMap<usize, char>, translate_map: FnvHashMap<usize, char>,
complement: bool,
s2_last: char,
} }
impl TranslateOperation { impl TranslateOperation {
fn new(set1: ExpandSet, set2: &mut ExpandSet, truncate: bool) -> TranslateOperation { fn new(
set1: ExpandSet,
set2: &mut ExpandSet,
truncate: bool,
complement: bool,
) -> TranslateOperation {
let mut map = FnvHashMap::default(); let mut map = FnvHashMap::default();
let mut s2_prev = '_'; let mut s2_prev = '_';
for i in set1 { for i in set1 {
@ -141,15 +148,27 @@ impl TranslateOperation {
map.insert(i as usize, s2_prev); map.insert(i as usize, s2_prev);
} }
} }
TranslateOperation { translate_map: map } TranslateOperation {
translate_map: map,
complement,
s2_last: s2_prev,
}
} }
} }
impl SymbolTranslator for TranslateOperation { impl SymbolTranslator for TranslateOperation {
fn translate(&self, c: char, _prev_c: char) -> Option<char> { fn translate(&self, c: char, _prev_c: char) -> Option<char> {
if self.complement {
Some(if self.translate_map.contains_key(&(c as usize)) {
c
} else {
self.s2_last
})
} else {
Some(*self.translate_map.get(&(c as usize)).unwrap_or(&c)) Some(*self.translate_map.get(&(c as usize)).unwrap_or(&c))
} }
} }
}
fn translate_input<T: SymbolTranslator>( fn translate_input<T: SymbolTranslator>(
input: &mut dyn BufRead, input: &mut dyn BufRead,
@ -256,11 +275,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
return 1; return 1;
} }
if complement_flag && !delete_flag && !squeeze_flag {
show_error!("-c is only supported with -d or -s");
return 1;
}
let stdin = stdin(); let stdin = stdin();
let mut locked_stdin = stdin.lock(); let mut locked_stdin = stdin.lock();
let stdout = stdout(); let stdout = stdout();
@ -282,8 +296,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
translate_input(&mut locked_stdin, &mut buffered_stdout, op); translate_input(&mut locked_stdin, &mut buffered_stdout, op);
} else { } else {
let mut set2 = ExpandSet::new(sets[1].as_ref()); let mut set2 = ExpandSet::new(sets[1].as_ref());
let op = TranslateOperation::new(set1, &mut set2, truncate_flag); let op = TranslateOperation::new(set1, &mut set2, truncate_flag, complement_flag);
translate_input(&mut locked_stdin, &mut buffered_stdout, op) translate_input(&mut locked_stdin, &mut buffered_stdout, op);
} }
0 0

View file

@ -45,6 +45,33 @@ fn test_delete_complement() {
.stdout_is("ac"); .stdout_is("ac");
} }
#[test]
fn test_complement1() {
new_ucmd!()
.args(&["-c", "a", "X"])
.pipe_in("ab")
.run()
.stdout_is("aX");
}
#[test]
fn test_complement2() {
new_ucmd!()
.args(&["-c", "0-9", "x"])
.pipe_in("Phone: 01234 567890")
.run()
.stdout_is("xxxxxxx01234x567890");
}
#[test]
fn test_complement3() {
new_ucmd!()
.args(&["-c", "abcdefgh", "123"])
.pipe_in("the cat and the bat")
.run()
.stdout_is("3he3ca33a3d33he3ba3");
}
#[test] #[test]
fn test_squeeze() { fn test_squeeze() {
new_ucmd!() new_ucmd!()