diff options
-rw-r--r-- | coreutils/tr.c | 58 |
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 @@ | |||
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include <stdlib.h> | 29 | #include <stdlib.h> |
30 | #include <unistd.h> | 30 | #include <unistd.h> |
31 | #include <ctype.h> | ||
31 | #include <sys/types.h> | 32 | #include <sys/types.h> |
32 | #include "busybox.h" | 33 | #include "busybox.h" |
33 | 34 | ||
34 | /* This must be a #define, since when CONFIG_DEBUG and BUFFERS_GO_IN_BSS are | ||
35 | * enabled, we otherwise get a "storage size isn't constant error. */ | ||
36 | #define ASCII 0377 | 35 | #define ASCII 0377 |
37 | 36 | ||
38 | /* some "globals" shared across this file */ | 37 | /* some "globals" shared across this file */ |
@@ -93,6 +92,7 @@ static void map(register unsigned char *string1, unsigned int string1_len, | |||
93 | /* supported constructs: | 92 | /* supported constructs: |
94 | * Ranges, e.g., [0-9] ==> 0123456789 | 93 | * Ranges, e.g., [0-9] ==> 0123456789 |
95 | * Escapes, e.g., \a ==> Control-G | 94 | * Escapes, e.g., \a ==> Control-G |
95 | * Character classes, e.g. [:upper:] ==> A ... Z | ||
96 | */ | 96 | */ |
97 | static unsigned int expand(const char *arg, register unsigned char *buffer) | 97 | static unsigned int expand(const char *arg, register unsigned char *buffer) |
98 | { | 98 | { |
@@ -115,12 +115,64 @@ static unsigned int expand(const char *arg, register unsigned char *buffer) | |||
115 | arg += 3; /* Skip the assumed a-z */ | 115 | arg += 3; /* Skip the assumed a-z */ |
116 | } else if (*arg == '[') { | 116 | } else if (*arg == '[') { |
117 | arg++; | 117 | arg++; |
118 | i = *arg++; | 118 | if (ENABLE_FEATURE_TR_CLASSES && *arg++ == ':') { |
119 | if (strncmp(arg, "alpha", 5) == 0) { | ||
120 | for (i = 'A'; i <= 'Z'; i++) | ||
121 | *buffer++ = i; | ||
122 | for (i = 'a'; i <= 'z'; i++) | ||
123 | *buffer++ = i; | ||
124 | } | ||
125 | else if (strncmp(arg, "alnum", 5) == 0) { | ||
126 | for (i = 'A'; i <= 'Z'; i++) | ||
127 | *buffer++ = i; | ||
128 | for (i = 'a'; i <= 'z'; i++) | ||
129 | *buffer++ = i; | ||
130 | for (i = '0'; i <= '9'; i++) | ||
131 | *buffer++ = i; | ||
132 | } | ||
133 | else if (strncmp(arg, "digit", 5) == 0) | ||
134 | for (i = '0'; i <= '9'; i++) | ||
135 | *buffer++ = i; | ||
136 | else if (strncmp(arg, "lower", 5) == 0) | ||
137 | for (i = 'a'; i <= 'z'; i++) | ||
138 | *buffer++ = i; | ||
139 | else if (strncmp(arg, "upper", 5) == 0) | ||
140 | for (i = 'A'; i <= 'Z'; i++) | ||
141 | *buffer++ = i; | ||
142 | else if (strncmp(arg, "space", 5) == 0) | ||
143 | strcat(buffer, " \f\n\r\t\v"); | ||
144 | else if (strncmp(arg, "blank", 5) == 0) | ||
145 | strcat(buffer, " \t"); | ||
146 | /* gcc gives a warning if braces aren't used here */ | ||
147 | else if (strncmp(arg, "punct", 5) == 0) { | ||
148 | for (i = 0; i <= ASCII; i++) | ||
149 | if (isprint(i) && (!isalnum(i)) && (!isspace(i))) | ||
150 | *buffer++ = i; | ||
151 | } | ||
152 | else if (strncmp(arg, "cntrl", 5) == 0) { | ||
153 | for (i = 0; i <= ASCII; i++) | ||
154 | if (iscntrl(i)) | ||
155 | *buffer++ = i; | ||
156 | } | ||
157 | else { | ||
158 | strcat(buffer, "[:"); | ||
159 | arg++; | ||
160 | continue; | ||
161 | } | ||
162 | break; | ||
163 | } | ||
164 | if (ENABLE_FEATURE_TR_EQUIV && *arg++ == '=') { | ||
165 | *buffer++ = *arg; | ||
166 | /* skip the closing =] */ | ||
167 | arg += 3; | ||
168 | continue; | ||
169 | } | ||
119 | if (*arg++ != '-') { | 170 | if (*arg++ != '-') { |
120 | *buffer++ = '['; | 171 | *buffer++ = '['; |
121 | arg -= 2; | 172 | arg -= 2; |
122 | continue; | 173 | continue; |
123 | } | 174 | } |
175 | i = *arg++; | ||
124 | ac = *arg++; | 176 | ac = *arg++; |
125 | while (i <= ac) | 177 | while (i <= ac) |
126 | *buffer++ = i++; | 178 | *buffer++ = i++; |