aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtests/tr.test11
-rw-r--r--toys/pending/tr.c27
2 files changed, 22 insertions, 16 deletions
diff --git a/tests/tr.test b/tests/tr.test
new file mode 100755
index 00000000..bb00a3ff
--- /dev/null
+++ b/tests/tr.test
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+[ -f testing.sh ] && . testing.sh
+
+#testing "name" "command" "result" "infile" "stdin"
+
+testing "" "tr 1 2" "223223223" "" "123123123"
+testing "-d" "tr -d 1" "232323" "" "123123123"
+testing "-s" "tr -s 1" "12223331222333" "" "111222333111222333"
+
+testing "no pathological flushing" "seq 10000000 | tr 1 2 > /dev/null" "" "" ""
diff --git a/toys/pending/tr.c b/toys/pending/tr.c
index 9a823f67..e68ae464 100644
--- a/toys/pending/tr.c
+++ b/toys/pending/tr.c
@@ -210,26 +210,21 @@ save:
static void print_map(char *set1, char *set2)
{
- int r = 0, i, prev_char = -1;
+ int n, src, dst, prev = -1;
- while (1)
- {
- i = 0;
- r = read(STDIN_FILENO, (toybuf), sizeof(toybuf));
- if (!r) break;
- for (;r > i;i++) {
+ while ((n = read(0, toybuf, sizeof(toybuf)))) {
+ if (!FLAG(d) && !FLAG(s)) {
+ for (dst = 0; dst < n; dst++) toybuf[dst] = TT.map[toybuf[dst]];
+ } else {
+ for (src = dst = 0; src < n; src++) {
+ int ch = TT.map[toybuf[src]];
- if ((toys.optflags & FLAG_d) && (TT.map[(int)toybuf[i]] & 0x100)) continue;
- if (toys.optflags & FLAG_s) {
- if ((TT.map[(int)toybuf[i]] & 0x200) &&
- (prev_char == TT.map[(int)toybuf[i]])) {
- continue;
- }
+ if (FLAG(d) && (ch & 0x100)) continue;
+ if (FLAG(s) && ((ch & 0x200) && prev == ch)) continue;
+ toybuf[dst++] = prev = ch;
}
- xputc(TT.map[(int)toybuf[i]] & 0xFF);
- prev_char = TT.map[(int)toybuf[i]];
- fflush(stdout);
}
+ xwrite(1, toybuf, dst);
}
}