Skip to content
Snippets Groups Projects
Commit 61383d42 authored by Frederic Danis's avatar Frederic Danis
Browse files

d/patches: backport upstream fixes for tr


Backport upstream fixes as `tr` fails to replace characters in squeeze-repeats
mode

Signed-off-by: default avatarFrédéric Danis <frederic.danis@collabora.com>
parent 1dc76f57
No related branches found
No related tags found
1 merge request!5d/patches: backport upstream fixes for tr
From 5674d093275ea9ddc3be9ffbb3627eb5d6cae3a1 Mon Sep 17 00:00:00 2001
From: Jeffrey Finkelstein <jeffrey.finkelstein@protonmail.com>
Date: Sat, 1 May 2021 13:01:55 -0400
Subject: [PATCH] fixup! tr: implement translate and squeeze (-s) mode
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
---
src/uu/tr/src/tr.rs | 89 +++++++++++++++++++++------------------------
1 file changed, 42 insertions(+), 47 deletions(-)
diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs
index 09c4304a..e04737a4 100644
--- a/src/uu/tr/src/tr.rs
+++ b/src/uu/tr/src/tr.rs
@@ -151,6 +151,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,
@@ -168,8 +197,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
});
@@ -282,53 +314,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let op = SqueezeOperation::new(set1, complement_flag);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
} else {
- // Define a closure that computes the translation using a hash map.
- //
- // The `unwrap()` should never panic because the
- // `TranslateOperation.translate()` method always returns
- // `Some`.
let mut set2 = ExpandSet::new(sets[1].as_ref());
- let translator = TranslateOperation::new(set1, &mut set2, truncate_flag);
- let translate = |c| translator.translate(c, 0 as char).unwrap();
-
- // Prepare some variables to be used for the closure that
- // computes the squeeze operation.
- //
- // The `squeeze()` closure needs to be defined anew for
- // each line of input, but these variables do not change
- // while reading the input so they can be defined before
- // the `while` loop.
- let set2 = ExpandSet::new(sets[1].as_ref());
- let squeezer = SqueezeOperation::new(set2, complement_flag);
-
- // Prepare some memory to read each line of the input (`buf`) and to write
- let mut buf = String::with_capacity(BUFFER_LEN + 4);
-
- // Loop over each line of stdin.
- while let Ok(length) = locked_stdin.read_line(&mut buf) {
- if length == 0 {
- break;
- }
-
- // Define a closure that computes the squeeze operation.
- //
- // We keep track of the previously seen character on
- // each call to `squeeze()`, but we need to reset the
- // `prev_c` variable at the beginning of each line of
- // the input. That's why we define the closure inside
- // the `while` loop.
- let mut prev_c = 0 as char;
- let squeeze = |c| {
- let result = squeezer.translate(c, prev_c);
- prev_c = c;
- result
- };
-
- // First translate, then squeeze each character of the input line.
- let filtered: String = buf.chars().map(translate).filter_map(squeeze).collect();
- buf.clear();
- buffered_stdout.write_all(filtered.as_bytes()).unwrap();
- }
+ 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());
--
2.25.1
...@@ -16,6 +16,12 @@ Sort-Various-fixes-and-performance-improvements.patch ...@@ -16,6 +16,12 @@ Sort-Various-fixes-and-performance-improvements.patch
sort-implement-k-and-t-support.patch sort-implement-k-and-t-support.patch
cp-improve-symlink-handling.patch cp-improve-symlink-handling.patch
cp-move-symlink-check-to-the-right-place.patch cp-move-symlink-check-to-the-right-place.patch
tr-implement-complement-separately-from-delete-or-sq.patch
tr-fix-complement-if-set2-is-range.patch
tr-implement-translate-and-squeeze-s-mode.patch
fixup-tr-implement-translate-and-squeeze-s-mode.patch
tr-fix-merge-conflict.patch
tr-fix-squeeze-and-complement-with-two-sets-2485.patch
# Apertis patches # Apertis patches
sort-fix-dependencies-versions.patch sort-fix-dependencies-versions.patch
......
From 34c22dc3ad359ebdd08ebbfcf6d3651c433de2df Mon Sep 17 00:00:00 2001
From: Jan Scheer <jhscheer@users.noreply.github.com>
Date: Sun, 2 May 2021 12:15:16 +0200
Subject: [PATCH] tr: fix complement if set2 is range
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
---
src/uu/tr/src/tr.rs | 2 +-
tests/by-util/test_tr.rs | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs
index b1143b4b..68543229 100644
--- a/src/uu/tr/src/tr.rs
+++ b/src/uu/tr/src/tr.rs
@@ -149,7 +149,7 @@ impl TranslateOperation {
TranslateOperation {
translate_map: map,
complement,
- s2_last: s2_prev,
+ s2_last: set2.last().unwrap_or(s2_prev),
}
}
}
diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs
index 064fbf77..f840dee6 100644
--- a/tests/by-util/test_tr.rs
+++ b/tests/by-util/test_tr.rs
@@ -86,6 +86,26 @@ fn test_complement3() {
.stdout_is("3he3ca33a3d33he3ba3");
}
+#[test]
+fn test_complement4() {
+ // $ echo -n '0x1y2z3' | tr -c '0-@' '*-~'
+ // 0~1~2~3
+ new_ucmd!()
+ .args(&["-c", "0-@", "*-~"])
+ .pipe_in("0x1y2z3")
+ .run()
+ .stdout_is("0~1~2~3");
+
+ // TODO: fix this
+ // $ echo '0x1y2z3' | tr -c '\0-@' '*-~'
+ // 0a1b2c3
+ // new_ucmd!()
+ // .args(&["-c", "\\0-@", "*-~"])
+ // .pipe_in("0x1y2z3")
+ // .run()
+ // .stdout_is("0a1b2c3");
+}
+
#[test]
fn test_squeeze() {
new_ucmd!()
--
2.25.1
From 000bd73edceae756be09693d4f7db9ed5899210a Mon Sep 17 00:00:00 2001
From: Jan Scheer <jhscheer@users.noreply.github.com>
Date: Sun, 2 May 2021 12:39:25 +0200
Subject: [PATCH] tr: fix merge conflict
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
---
src/uu/tr/src/tr.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs
index 5e6c41a8..dcb64a12 100644
--- a/src/uu/tr/src/tr.rs
+++ b/src/uu/tr/src/tr.rs
@@ -182,7 +182,7 @@ impl TranslateAndSqueezeOperation {
complement: bool,
) -> TranslateAndSqueezeOperation {
TranslateAndSqueezeOperation {
- translate: TranslateOperation::new(set1, set2, truncate),
+ translate: TranslateOperation::new(set1, set2, truncate, complement),
squeeze: SqueezeOperation::new(set2_, complement),
}
}
--
2.25.1
From 30b80d0c82634451d855865125c99a54f98aad19 Mon Sep 17 00:00:00 2001
From: Jan Scheer <jhscheer@users.noreply.github.com>
Date: Fri, 9 Jul 2021 22:55:00 +0200
Subject: [PATCH] tr: fix squeeze and complement with two sets (#2485)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
---
src/uu/tr/src/tr.rs | 26 ++++++++------------------
tests/by-util/test_tr.rs | 9 +++++++++
2 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs
index 28ce70c2..2abc652f 100644
--- a/src/uu/tr/src/tr.rs
+++ b/src/uu/tr/src/tr.rs
@@ -173,16 +173,14 @@ struct TranslateAndSqueezeOperation {
}
impl TranslateAndSqueezeOperation {
- fn new(
- set1: ExpandSet,
- set2: &mut ExpandSet,
- set2_: ExpandSet,
- truncate: bool,
- complement: bool,
- ) -> TranslateAndSqueezeOperation {
+ fn new(sets: Vec<String>, truncate: bool, complement: bool) -> TranslateAndSqueezeOperation {
+ let set1 = ExpandSet::new(sets[0].as_ref());
+ let set1_ = ExpandSet::new(sets[0].as_ref());
+ let mut set2 = ExpandSet::new(sets[1].as_ref());
+ let set2_ = ExpandSet::new(sets[1].as_ref());
TranslateAndSqueezeOperation {
- translate: TranslateOperation::new(set1, set2, truncate, complement),
- squeeze: SqueezeOperation::new(set2_, complement),
+ translate: TranslateOperation::new(set1, &mut set2, truncate, complement),
+ squeeze: SqueezeOperation::new(if complement { set1_ } else { set2_ }, complement),
}
}
}
@@ -302,15 +300,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
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,
- );
+ let op = TranslateAndSqueezeOperation::new(sets, truncate_flag, complement_flag);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
}
} else {
diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs
index 936af2ca..07e3a843 100644
--- a/tests/by-util/test_tr.rs
+++ b/tests/by-util/test_tr.rs
@@ -127,6 +127,15 @@ fn test_squeeze_complement() {
.stdout_is("aaBcDcc");
}
+#[test]
+fn test_squeeze_complement_two_sets() {
+ new_ucmd!()
+ .args(&["-sc", "a", "_"])
+ .pipe_in("test a aa with 3 ___ spaaaces +++") // spell-checker:disable-line
+ .run()
+ .stdout_is("_a_aa_aaa_");
+}
+
#[test]
fn test_translate_and_squeeze() {
new_ucmd!()
--
2.25.1
From 117e84eed3adabb54fa852030712848f08c319f1 Mon Sep 17 00:00:00 2001
From: Jan Scheer <jhscheer@users.noreply.github.com>
Date: Sat, 1 May 2021 18:46:13 +0200
Subject: [PATCH] tr: implement complement separately from delete or squeeze
(#2147)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
---
src/uu/tr/src/tr.rs | 34 ++++++++++++++++++++++++----------
tests/by-util/test_tr.rs | 27 +++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs
index 6c1c0746..f8fabd69 100644
--- a/src/uu/tr/src/tr.rs
+++ b/src/uu/tr/src/tr.rs
@@ -125,10 +125,17 @@ impl SymbolTranslator for DeleteAndSqueezeOperation {
struct TranslateOperation {
translate_map: FnvHashMap<usize, char>,
+ complement: bool,
+ s2_last: char,
}
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 s2_prev = '_';
for i in set1 {
@@ -141,13 +148,25 @@ impl TranslateOperation {
map.insert(i as usize, s2_prev);
}
}
- TranslateOperation { translate_map: map }
+ TranslateOperation {
+ translate_map: map,
+ complement,
+ s2_last: s2_prev,
+ }
}
}
impl SymbolTranslator for TranslateOperation {
fn translate(&self, c: char, _prev_c: char) -> Option<char> {
- Some(*self.translate_map.get(&(c as usize)).unwrap_or(&c))
+ 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))
+ }
}
}
@@ -256,11 +275,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
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 mut locked_stdin = stdin.lock();
let stdout = stdout();
@@ -282,8 +296,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
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);
- translate_input(&mut locked_stdin, &mut buffered_stdout, op)
+ let op = TranslateOperation::new(set1, &mut set2, truncate_flag, complement_flag);
+ translate_input(&mut locked_stdin, &mut buffered_stdout, op);
}
0
diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs
index 630c305c..637c9b10 100644
--- a/tests/by-util/test_tr.rs
+++ b/tests/by-util/test_tr.rs
@@ -45,6 +45,33 @@ fn test_delete_complement() {
.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]
fn test_squeeze() {
new_ucmd!()
--
2.25.1
From 0f3bc237393adef485182656b0edc986575c592d Mon Sep 17 00:00:00 2001
From: Jeffrey Finkelstein <jeffrey.finkelstein@protonmail.com>
Date: Thu, 29 Apr 2021 23:13:20 -0400
Subject: [PATCH] tr: implement translate and squeeze (-s) mode
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
Add translate and squeeze mode to the `tr` program. For example:
$ printf xx | tr -s x y
y
Fixes #2141.
---
src/uu/tr/src/tr.rs | 54 ++++++++++++++++++++++++++++++++++++++--
tests/by-util/test_tr.rs | 18 ++++++++++++++
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs
index 6c1c0746..09c4304a 100644
--- a/src/uu/tr/src/tr.rs
+++ b/src/uu/tr/src/tr.rs
@@ -278,8 +278,58 @@ 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 {
+ // Define a closure that computes the translation using a hash map.
+ //
+ // The `unwrap()` should never panic because the
+ // `TranslateOperation.translate()` method always returns
+ // `Some`.
+ let mut set2 = ExpandSet::new(sets[1].as_ref());
+ let translator = TranslateOperation::new(set1, &mut set2, truncate_flag);
+ let translate = |c| translator.translate(c, 0 as char).unwrap();
+
+ // Prepare some variables to be used for the closure that
+ // computes the squeeze operation.
+ //
+ // The `squeeze()` closure needs to be defined anew for
+ // each line of input, but these variables do not change
+ // while reading the input so they can be defined before
+ // the `while` loop.
+ let set2 = ExpandSet::new(sets[1].as_ref());
+ let squeezer = SqueezeOperation::new(set2, complement_flag);
+
+ // Prepare some memory to read each line of the input (`buf`) and to write
+ let mut buf = String::with_capacity(BUFFER_LEN + 4);
+
+ // Loop over each line of stdin.
+ while let Ok(length) = locked_stdin.read_line(&mut buf) {
+ if length == 0 {
+ break;
+ }
+
+ // Define a closure that computes the squeeze operation.
+ //
+ // We keep track of the previously seen character on
+ // each call to `squeeze()`, but we need to reset the
+ // `prev_c` variable at the beginning of each line of
+ // the input. That's why we define the closure inside
+ // the `while` loop.
+ let mut prev_c = 0 as char;
+ let squeeze = |c| {
+ let result = squeezer.translate(c, prev_c);
+ prev_c = c;
+ result
+ };
+
+ // First translate, then squeeze each character of the input line.
+ let filtered: String = buf.chars().map(translate).filter_map(squeeze).collect();
+ buf.clear();
+ buffered_stdout.write_all(filtered.as_bytes()).unwrap();
+ }
+ }
} else {
let mut set2 = ExpandSet::new(sets[1].as_ref());
let op = TranslateOperation::new(set1, &mut set2, truncate_flag, complement_flag);
diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs
index 630c305c..5d044a18 100644
--- a/tests/by-util/test_tr.rs
+++ b/tests/by-util/test_tr.rs
@@ -63,6 +63,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!()
--
2.25.1
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment