summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley2006-04-19 22:22:06 +0000
committerRob Landley2006-04-19 22:22:06 +0000
commit998dbee6d9494c4dee29a2abe195d79d9b1c2e08 (patch)
tree3c5c6d2e1cfe06cb2fbd7bc41d5076b75976b595
parent5076eb4af923ec2d3355450cfa356dbac9f5aeca (diff)
downloadbusybox-998dbee6d9494c4dee29a2abe195d79d9b1c2e08.zip
busybox-998dbee6d9494c4dee29a2abe195d79d9b1c2e08.tar.gz
Patch from Jean Wolter:
it looks like the introduced support for character classes and equivalence classes is not correct. The attached patch tries to fix some symptoms and tries to make tr behave like gnu tr for the added test cases. The patch  - removes if clauses with side effects  - fixes handling of buffer pointer (strcat added characters to the    buffer without increasing the buffer pointer)  - re-arranges character classes to match ASCII order regards, Jean
-rw-r--r--coreutils/tr.c27
-rw-r--r--testsuite/tr/tr-works29
2 files changed, 38 insertions, 18 deletions
diff --git a/coreutils/tr.c b/coreutils/tr.c
index 15a9d17..752b13b 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -116,7 +116,8 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
arg += 3; /* Skip the assumed a-z */
} else if (*arg == '[') {
arg++;
- if (ENABLE_FEATURE_TR_CLASSES && *arg++ == ':') {
+ i = *arg++;
+ if (ENABLE_FEATURE_TR_CLASSES && i == ':') {
if (strncmp(arg, "alpha", 5) == 0) {
for (i = 'A'; i <= 'Z'; i++)
*buffer++ = i;
@@ -124,12 +125,12 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
*buffer++ = i;
}
else if (strncmp(arg, "alnum", 5) == 0) {
+ for (i = '0'; i <= '9'; i++)
+ *buffer++ = i;
for (i = 'A'; i <= 'Z'; i++)
*buffer++ = i;
for (i = 'a'; i <= 'z'; i++)
*buffer++ = i;
- for (i = '0'; i <= '9'; i++)
- *buffer++ = i;
}
else if (strncmp(arg, "digit", 5) == 0)
for (i = '0'; i <= '9'; i++)
@@ -140,10 +141,15 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
else if (strncmp(arg, "upper", 5) == 0)
for (i = 'A'; i <= 'Z'; i++)
*buffer++ = i;
- else if (strncmp(arg, "space", 5) == 0)
- strcat((char*)buffer, " \f\n\r\t\v");
- else if (strncmp(arg, "blank", 5) == 0)
- strcat((char*)buffer, " \t");
+ else if (strncmp(arg, "space", 5) == 0) {
+ const char s[] = "\t\n\v\f\r ";
+ strcat((char*)buffer, s);
+ buffer += sizeof(s) - 1;
+ }
+ else if (strncmp(arg, "blank", 5) == 0) {
+ *buffer++ = '\t';
+ *buffer++ = ' ';
+ }
/* gcc gives a warning if braces aren't used here */
else if (strncmp(arg, "punct", 5) == 0) {
for (i = 0; i <= ASCII; i++)
@@ -156,13 +162,13 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
*buffer++ = i;
}
else {
- strcat((char*)buffer, "[:");
- arg++;
+ *buffer++ = '[';
+ *buffer++ = ':';
continue;
}
break;
}
- if (ENABLE_FEATURE_TR_EQUIV && *arg++ == '=') {
+ if (ENABLE_FEATURE_TR_EQUIV && i == '=') {
*buffer++ = *arg;
/* skip the closing =] */
arg += 3;
@@ -173,7 +179,6 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
arg -= 2;
continue;
}
- i = *arg++;
ac = *arg++;
while (i <= ac)
*buffer++ = i++;
diff --git a/testsuite/tr/tr-works b/testsuite/tr/tr-works
index 8753a3f..b7a6e8d 100644
--- a/testsuite/tr/tr-works
+++ b/testsuite/tr/tr-works
@@ -1,9 +1,24 @@
-echo "cbaab" | tr abc zyx > logfile.gnu
-echo "TESTING A B C" | tr [A-Z] [a-z] >> logfile.gnu
-echo abc[] | tr a[b AXB >> logfile.gnu
-
-echo "cbaab" | busybox tr abc zyx > logfile.bb
-echo "TESTING A B C" | busybox tr [A-Z] [a-z] >> logfile.bb
-echo abc[] | busybox tr a[b AXB >> logfile.bb
+run_tr ()
+{
+ echo -n "echo '$1' | tr '$2' '$3': "
+ echo "$1" | $bb tr "$2" "$3"
+ echo
+}
+tr_test ()
+{
+ run_tr "cbaab" abc zyx
+ run_tr "TESTING A B C" '[A-Z]' '[a-z]'
+ run_tr "abc[]" "a[b" AXB
+ run_tr abc '[:alpha:]' A-ZA-Z
+ run_tr abc56 '[:alnum:]' A-ZA-Zxxxxxxxxxx
+ run_tr 012 '[:digit:]' abcdefghi
+ run_tr abc56 '[:lower:]' '[:upper:]'
+ run_tr " " '[:space:]' 12345
+ run_tr " " '[:blank:]' 12
+ run_tr 'a b' '[= =]' X
+ run_tr "[:" '[:' ab
+}
+bb= tr_test > logfile.gnu
+bb=busybox tr_test > logfile.bb
cmp logfile.gnu logfile.bb