aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/tr.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/coreutils/tr.c b/coreutils/tr.c
index 1325245b8..6e3f97b36 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -28,11 +28,10 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ctype.h>
#include <sys/types.h>
#include "busybox.h"
-/* This must be a #define, since when CONFIG_DEBUG and BUFFERS_GO_IN_BSS are
- * enabled, we otherwise get a "storage size isn't constant error. */
#define ASCII 0377
/* some "globals" shared across this file */
@@ -93,6 +92,7 @@ static void map(register unsigned char *string1, unsigned int string1_len,
/* supported constructs:
* Ranges, e.g., [0-9] ==> 0123456789
* Escapes, e.g., \a ==> Control-G
+ * Character classes, e.g. [:upper:] ==> A ... Z
*/
static unsigned int expand(const char *arg, register unsigned char *buffer)
{
@@ -115,12 +115,64 @@ static unsigned int expand(const char *arg, register unsigned char *buffer)
arg += 3; /* Skip the assumed a-z */
} else if (*arg == '[') {
arg++;
- i = *arg++;
+ if (ENABLE_FEATURE_TR_CLASSES && *arg++ == ':') {
+ if (strncmp(arg, "alpha", 5) == 0) {
+ for (i = 'A'; i <= 'Z'; i++)
+ *buffer++ = i;
+ for (i = 'a'; i <= 'z'; i++)
+ *buffer++ = i;
+ }
+ else if (strncmp(arg, "alnum", 5) == 0) {
+ 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++)
+ *buffer++ = i;
+ else if (strncmp(arg, "lower", 5) == 0)
+ for (i = 'a'; i <= 'z'; i++)
+ *buffer++ = i;
+ else if (strncmp(arg, "upper", 5) == 0)
+ for (i = 'A'; i <= 'Z'; i++)
+ *buffer++ = i;
+ else if (strncmp(arg, "space", 5) == 0)
+ strcat(buffer, " \f\n\r\t\v");
+ else if (strncmp(arg, "blank", 5) == 0)
+ strcat(buffer, " \t");
+ /* gcc gives a warning if braces aren't used here */
+ else if (strncmp(arg, "punct", 5) == 0) {
+ for (i = 0; i <= ASCII; i++)
+ if (isprint(i) && (!isalnum(i)) && (!isspace(i)))
+ *buffer++ = i;
+ }
+ else if (strncmp(arg, "cntrl", 5) == 0) {
+ for (i = 0; i <= ASCII; i++)
+ if (iscntrl(i))
+ *buffer++ = i;
+ }
+ else {
+ strcat(buffer, "[:");
+ arg++;
+ continue;
+ }
+ break;
+ }
+ if (ENABLE_FEATURE_TR_EQUIV && *arg++ == '=') {
+ *buffer++ = *arg;
+ /* skip the closing =] */
+ arg += 3;
+ continue;
+ }
if (*arg++ != '-') {
*buffer++ = '[';
arg -= 2;
continue;
}
+ i = *arg++;
ac = *arg++;
while (i <= ac)
*buffer++ = i++;