aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2006-04-19 22:22:06 +0000
committerRob Landley <rob@landley.net>2006-04-19 22:22:06 +0000
commit998dbee6d9494c4dee29a2abe195d79d9b1c2e08 (patch)
tree3c5c6d2e1cfe06cb2fbd7bc41d5076b75976b595
parent5076eb4af923ec2d3355450cfa356dbac9f5aeca (diff)
downloadbusybox-w32-998dbee6d9494c4dee29a2abe195d79d9b1c2e08.tar.gz
busybox-w32-998dbee6d9494c4dee29a2abe195d79d9b1c2e08.tar.bz2
busybox-w32-998dbee6d9494c4dee29a2abe195d79d9b1c2e08.zip
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 15a9d17b0..752b13bf8 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -116,7 +116,8 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
116 arg += 3; /* Skip the assumed a-z */ 116 arg += 3; /* Skip the assumed a-z */
117 } else if (*arg == '[') { 117 } else if (*arg == '[') {
118 arg++; 118 arg++;
119 if (ENABLE_FEATURE_TR_CLASSES && *arg++ == ':') { 119 i = *arg++;
120 if (ENABLE_FEATURE_TR_CLASSES && i == ':') {
120 if (strncmp(arg, "alpha", 5) == 0) { 121 if (strncmp(arg, "alpha", 5) == 0) {
121 for (i = 'A'; i <= 'Z'; i++) 122 for (i = 'A'; i <= 'Z'; i++)
122 *buffer++ = i; 123 *buffer++ = i;
@@ -124,12 +125,12 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
124 *buffer++ = i; 125 *buffer++ = i;
125 } 126 }
126 else if (strncmp(arg, "alnum", 5) == 0) { 127 else if (strncmp(arg, "alnum", 5) == 0) {
128 for (i = '0'; i <= '9'; i++)
129 *buffer++ = i;
127 for (i = 'A'; i <= 'Z'; i++) 130 for (i = 'A'; i <= 'Z'; i++)
128 *buffer++ = i; 131 *buffer++ = i;
129 for (i = 'a'; i <= 'z'; i++) 132 for (i = 'a'; i <= 'z'; i++)
130 *buffer++ = i; 133 *buffer++ = i;
131 for (i = '0'; i <= '9'; i++)
132 *buffer++ = i;
133 } 134 }
134 else if (strncmp(arg, "digit", 5) == 0) 135 else if (strncmp(arg, "digit", 5) == 0)
135 for (i = '0'; i <= '9'; i++) 136 for (i = '0'; i <= '9'; i++)
@@ -140,10 +141,15 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
140 else if (strncmp(arg, "upper", 5) == 0) 141 else if (strncmp(arg, "upper", 5) == 0)
141 for (i = 'A'; i <= 'Z'; i++) 142 for (i = 'A'; i <= 'Z'; i++)
142 *buffer++ = i; 143 *buffer++ = i;
143 else if (strncmp(arg, "space", 5) == 0) 144 else if (strncmp(arg, "space", 5) == 0) {
144 strcat((char*)buffer, " \f\n\r\t\v"); 145 const char s[] = "\t\n\v\f\r ";
145 else if (strncmp(arg, "blank", 5) == 0) 146 strcat((char*)buffer, s);
146 strcat((char*)buffer, " \t"); 147 buffer += sizeof(s) - 1;
148 }
149 else if (strncmp(arg, "blank", 5) == 0) {
150 *buffer++ = '\t';
151 *buffer++ = ' ';
152 }
147 /* gcc gives a warning if braces aren't used here */ 153 /* gcc gives a warning if braces aren't used here */
148 else if (strncmp(arg, "punct", 5) == 0) { 154 else if (strncmp(arg, "punct", 5) == 0) {
149 for (i = 0; i <= ASCII; i++) 155 for (i = 0; i <= ASCII; i++)
@@ -156,13 +162,13 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
156 *buffer++ = i; 162 *buffer++ = i;
157 } 163 }
158 else { 164 else {
159 strcat((char*)buffer, "[:"); 165 *buffer++ = '[';
160 arg++; 166 *buffer++ = ':';
161 continue; 167 continue;
162 } 168 }
163 break; 169 break;
164 } 170 }
165 if (ENABLE_FEATURE_TR_EQUIV && *arg++ == '=') { 171 if (ENABLE_FEATURE_TR_EQUIV && i == '=') {
166 *buffer++ = *arg; 172 *buffer++ = *arg;
167 /* skip the closing =] */ 173 /* skip the closing =] */
168 arg += 3; 174 arg += 3;
@@ -173,7 +179,6 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
173 arg -= 2; 179 arg -= 2;
174 continue; 180 continue;
175 } 181 }
176 i = *arg++;
177 ac = *arg++; 182 ac = *arg++;
178 while (i <= ac) 183 while (i <= ac)
179 *buffer++ = i++; 184 *buffer++ = i++;
diff --git a/testsuite/tr/tr-works b/testsuite/tr/tr-works
index 8753a3f28..b7a6e8df7 100644
--- a/testsuite/tr/tr-works
+++ b/testsuite/tr/tr-works
@@ -1,9 +1,24 @@
1echo "cbaab" | tr abc zyx > logfile.gnu 1run_tr ()
2echo "TESTING A B C" | tr [A-Z] [a-z] >> logfile.gnu 2{
3echo abc[] | tr a[b AXB >> logfile.gnu 3 echo -n "echo '$1' | tr '$2' '$3': "
4 4 echo "$1" | $bb tr "$2" "$3"
5echo "cbaab" | busybox tr abc zyx > logfile.bb 5 echo
6echo "TESTING A B C" | busybox tr [A-Z] [a-z] >> logfile.bb 6}
7echo abc[] | busybox tr a[b AXB >> logfile.bb 7tr_test ()
8{
9 run_tr "cbaab" abc zyx
10 run_tr "TESTING A B C" '[A-Z]' '[a-z]'
11 run_tr "abc[]" "a[b" AXB
12 run_tr abc '[:alpha:]' A-ZA-Z
13 run_tr abc56 '[:alnum:]' A-ZA-Zxxxxxxxxxx
14 run_tr 012 '[:digit:]' abcdefghi
15 run_tr abc56 '[:lower:]' '[:upper:]'
16 run_tr " " '[:space:]' 12345
17 run_tr " " '[:blank:]' 12
18 run_tr 'a b' '[= =]' X
19 run_tr "[:" '[:' ab
20}
8 21
22bb= tr_test > logfile.gnu
23bb=busybox tr_test > logfile.bb
9cmp logfile.gnu logfile.bb 24cmp logfile.gnu logfile.bb