aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
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 */
97static unsigned int expand(const char *arg, register unsigned char *buffer) 97static 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++;