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
This commit is contained in:
Rob Landley 2006-04-19 22:22:06 +00:00
parent 5076eb4af9
commit 998dbee6d9
2 changed files with 38 additions and 18 deletions

View File

@ -116,7 +116,8 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
arg += 3; /* Skip the assumed a-z */ arg += 3; /* Skip the assumed a-z */
} else if (*arg == '[') { } else if (*arg == '[') {
arg++; arg++;
if (ENABLE_FEATURE_TR_CLASSES && *arg++ == ':') { i = *arg++;
if (ENABLE_FEATURE_TR_CLASSES && i == ':') {
if (strncmp(arg, "alpha", 5) == 0) { if (strncmp(arg, "alpha", 5) == 0) {
for (i = 'A'; i <= 'Z'; i++) for (i = 'A'; i <= 'Z'; i++)
*buffer++ = i; *buffer++ = i;
@ -124,12 +125,12 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
*buffer++ = i; *buffer++ = i;
} }
else if (strncmp(arg, "alnum", 5) == 0) { else if (strncmp(arg, "alnum", 5) == 0) {
for (i = '0'; i <= '9'; i++)
*buffer++ = i;
for (i = 'A'; i <= 'Z'; i++) for (i = 'A'; i <= 'Z'; i++)
*buffer++ = i; *buffer++ = i;
for (i = 'a'; i <= 'z'; i++) for (i = 'a'; i <= 'z'; i++)
*buffer++ = i; *buffer++ = i;
for (i = '0'; i <= '9'; i++)
*buffer++ = i;
} }
else if (strncmp(arg, "digit", 5) == 0) else if (strncmp(arg, "digit", 5) == 0)
for (i = '0'; i <= '9'; i++) 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) else if (strncmp(arg, "upper", 5) == 0)
for (i = 'A'; i <= 'Z'; i++) for (i = 'A'; i <= 'Z'; i++)
*buffer++ = i; *buffer++ = i;
else if (strncmp(arg, "space", 5) == 0) else if (strncmp(arg, "space", 5) == 0) {
strcat((char*)buffer, " \f\n\r\t\v"); const char s[] = "\t\n\v\f\r ";
else if (strncmp(arg, "blank", 5) == 0) strcat((char*)buffer, s);
strcat((char*)buffer, " \t"); buffer += sizeof(s) - 1;
}
else if (strncmp(arg, "blank", 5) == 0) {
*buffer++ = '\t';
*buffer++ = ' ';
}
/* gcc gives a warning if braces aren't used here */ /* gcc gives a warning if braces aren't used here */
else if (strncmp(arg, "punct", 5) == 0) { else if (strncmp(arg, "punct", 5) == 0) {
for (i = 0; i <= ASCII; i++) for (i = 0; i <= ASCII; i++)
@ -156,13 +162,13 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
*buffer++ = i; *buffer++ = i;
} }
else { else {
strcat((char*)buffer, "[:"); *buffer++ = '[';
arg++; *buffer++ = ':';
continue; continue;
} }
break; break;
} }
if (ENABLE_FEATURE_TR_EQUIV && *arg++ == '=') { if (ENABLE_FEATURE_TR_EQUIV && i == '=') {
*buffer++ = *arg; *buffer++ = *arg;
/* skip the closing =] */ /* skip the closing =] */
arg += 3; arg += 3;
@ -173,7 +179,6 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
arg -= 2; arg -= 2;
continue; continue;
} }
i = *arg++;
ac = *arg++; ac = *arg++;
while (i <= ac) while (i <= ac)
*buffer++ = i++; *buffer++ = i++;

View File

@ -1,9 +1,24 @@
echo "cbaab" | tr abc zyx > logfile.gnu run_tr ()
echo "TESTING A B C" | tr [A-Z] [a-z] >> logfile.gnu {
echo abc[] | tr a[b AXB >> logfile.gnu echo -n "echo '$1' | tr '$2' '$3': "
echo "$1" | $bb tr "$2" "$3"
echo "cbaab" | busybox tr abc zyx > logfile.bb echo
echo "TESTING A B C" | busybox tr [A-Z] [a-z] >> logfile.bb }
echo abc[] | busybox tr a[b AXB >> logfile.bb 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 cmp logfile.gnu logfile.bb