diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-04 10:16:52 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-04 10:16:52 +0000 |
commit | 74324c86663f57a19c1de303ee8c8e5449db9ef2 (patch) | |
tree | 11f5da9de4212875ce5811be2e1050e076378c9a /coreutils/tr.c | |
parent | 4e5f82c76f08614d0b69f9ec4a8baac303af15f6 (diff) | |
download | busybox-w32-74324c86663f57a19c1de303ee8c8e5449db9ef2.tar.gz busybox-w32-74324c86663f57a19c1de303ee8c8e5449db9ef2.tar.bz2 busybox-w32-74324c86663f57a19c1de303ee8c8e5449db9ef2.zip |
Audit bb_common_bufsiz usage, add script which looks for misuse.
tr: stop using globals needlessly.
code: -103 bytes
Diffstat (limited to 'coreutils/tr.c')
-rw-r--r-- | coreutils/tr.c | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/coreutils/tr.c b/coreutils/tr.c index 7e89e9a80..c0d0dfacb 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c | |||
@@ -25,41 +25,9 @@ | |||
25 | #define TR_OPT_complement (1<<0) | 25 | #define TR_OPT_complement (1<<0) |
26 | #define TR_OPT_delete (1<<1) | 26 | #define TR_OPT_delete (1<<1) |
27 | #define TR_OPT_squeeze_reps (1<<2) | 27 | #define TR_OPT_squeeze_reps (1<<2) |
28 | /* some "globals" shared across this file */ | ||
29 | /* these last are pointers to static buffers declared in tr_main */ | ||
30 | static char *poutput, *pvector, *pinvec, *poutvec; | ||
31 | 28 | ||
32 | static void ATTRIBUTE_NORETURN convert(const smalluint flags) | 29 | static void map(char *pvector, |
33 | { | 30 | unsigned char *string1, unsigned int string1_len, |
34 | size_t read_chars = 0, in_index = 0, out_index = 0, c, coded, last = -1; | ||
35 | |||
36 | for (;;) { | ||
37 | /* If we're out of input, flush output and read more input. */ | ||
38 | if (in_index == read_chars) { | ||
39 | if (out_index) { | ||
40 | xwrite(STDOUT_FILENO, (char *)poutput, out_index); | ||
41 | out_index = 0; | ||
42 | } | ||
43 | if ((read_chars = read(STDIN_FILENO, bb_common_bufsiz1, BUFSIZ)) <= 0) { | ||
44 | if (write(STDOUT_FILENO, (char *)poutput, out_index) != out_index) | ||
45 | bb_perror_msg(bb_msg_write_error); | ||
46 | exit(EXIT_SUCCESS); | ||
47 | } | ||
48 | in_index = 0; | ||
49 | } | ||
50 | c = bb_common_bufsiz1[in_index++]; | ||
51 | coded = pvector[c]; | ||
52 | if ((flags & TR_OPT_delete) && pinvec[c]) | ||
53 | continue; | ||
54 | if ((flags & TR_OPT_squeeze_reps) && last == coded && | ||
55 | (pinvec[c] || poutvec[coded])) | ||
56 | continue; | ||
57 | poutput[out_index++] = last = coded; | ||
58 | } | ||
59 | /* NOTREACHED */ | ||
60 | } | ||
61 | |||
62 | static void map(unsigned char *string1, unsigned int string1_len, | ||
63 | unsigned char *string2, unsigned int string2_len) | 31 | unsigned char *string2, unsigned int string2_len) |
64 | { | 32 | { |
65 | char last = '0'; | 33 | char last = '0'; |
@@ -121,9 +89,9 @@ static unsigned int expand(const char *arg, char *buffer) | |||
121 | if (ENABLE_FEATURE_TR_CLASSES && i == ':') { | 89 | if (ENABLE_FEATURE_TR_CLASSES && i == ':') { |
122 | smalluint j; | 90 | smalluint j; |
123 | { /* not really pretty.. */ | 91 | { /* not really pretty.. */ |
124 | char *tmp = xstrndup(arg, 7); // warning: xdigit needs 8, not 7 | 92 | char *tmp = xstrndup(arg, 7); // warning: xdigit needs 8, not 7 |
125 | j = index_in_str_array(classes, tmp) + 1; | 93 | j = index_in_str_array(classes, tmp) + 1; |
126 | free(tmp); | 94 | free(tmp); |
127 | } | 95 | } |
128 | if (j == CLASS_alnum || j == CLASS_digit) { | 96 | if (j == CLASS_alnum || j == CLASS_digit) { |
129 | for (i = '0'; i <= '9'; i++) | 97 | for (i = '0'; i <= '9'; i++) |
@@ -183,7 +151,7 @@ static unsigned int expand(const char *arg, char *buffer) | |||
183 | 151 | ||
184 | static int complement(char *buffer, int buffer_len) | 152 | static int complement(char *buffer, int buffer_len) |
185 | { | 153 | { |
186 | short i, j, ix; | 154 | int i, j, ix; |
187 | char conv[ASCII + 2]; | 155 | char conv[ASCII + 2]; |
188 | 156 | ||
189 | ix = 0; | 157 | ix = 0; |
@@ -206,17 +174,12 @@ int tr_main(int argc, char **argv) | |||
206 | int idx = 1; | 174 | int idx = 1; |
207 | int i; | 175 | int i; |
208 | smalluint flags = 0; | 176 | smalluint flags = 0; |
177 | size_t read_chars = 0, in_index = 0, out_index = 0, c, coded, last = -1; | ||
209 | RESERVE_CONFIG_UBUFFER(output, BUFSIZ); | 178 | RESERVE_CONFIG_UBUFFER(output, BUFSIZ); |
210 | RESERVE_CONFIG_BUFFER(vector, ASCII+1); | 179 | RESERVE_CONFIG_BUFFER(vector, ASCII+1); |
211 | RESERVE_CONFIG_BUFFER(invec, ASCII+1); | 180 | RESERVE_CONFIG_BUFFER(invec, ASCII+1); |
212 | RESERVE_CONFIG_BUFFER(outvec, ASCII+1); | 181 | RESERVE_CONFIG_BUFFER(outvec, ASCII+1); |
213 | 182 | ||
214 | /* ... but make them available globally */ | ||
215 | poutput = output; | ||
216 | pvector = vector; | ||
217 | pinvec = invec; | ||
218 | poutvec = outvec; | ||
219 | |||
220 | if (argc > 1 && argv[idx][0] == '-') { | 183 | if (argc > 1 && argv[idx][0] == '-') { |
221 | for (ptr = (unsigned char *) &argv[idx][1]; *ptr; ptr++) { | 184 | for (ptr = (unsigned char *) &argv[idx][1]; *ptr; ptr++) { |
222 | if (*ptr == 'c') | 185 | if (*ptr == 'c') |
@@ -235,21 +198,47 @@ int tr_main(int argc, char **argv) | |||
235 | invec[i] = outvec[i] = FALSE; | 198 | invec[i] = outvec[i] = FALSE; |
236 | } | 199 | } |
237 | 200 | ||
201 | #define tr_buf bb_common_bufsiz1 | ||
238 | if (argv[idx] != NULL) { | 202 | if (argv[idx] != NULL) { |
239 | input_length = expand(argv[idx++], bb_common_bufsiz1); | 203 | input_length = expand(argv[idx++], tr_buf); |
240 | if (flags & TR_OPT_complement) | 204 | if (flags & TR_OPT_complement) |
241 | input_length = complement(bb_common_bufsiz1, input_length); | 205 | input_length = complement(tr_buf, input_length); |
242 | if (argv[idx] != NULL) { | 206 | if (argv[idx] != NULL) { |
243 | if (*argv[idx] == '\0') | 207 | if (*argv[idx] == '\0') |
244 | bb_error_msg_and_die("STRING2 cannot be empty"); | 208 | bb_error_msg_and_die("STRING2 cannot be empty"); |
245 | output_length = expand(argv[idx], output); | 209 | output_length = expand(argv[idx], output); |
246 | map(bb_common_bufsiz1, input_length, output, output_length); | 210 | map(vector, tr_buf, input_length, output, output_length); |
247 | } | 211 | } |
248 | for (i = 0; i < input_length; i++) | 212 | for (i = 0; i < input_length; i++) |
249 | invec[(unsigned char)bb_common_bufsiz1[i]] = TRUE; | 213 | invec[(unsigned char)tr_buf[i]] = TRUE; |
250 | for (i = 0; i < output_length; i++) | 214 | for (i = 0; i < output_length; i++) |
251 | outvec[output[i]] = TRUE; | 215 | outvec[output[i]] = TRUE; |
252 | } | 216 | } |
253 | convert(flags); | 217 | |
218 | for (;;) { | ||
219 | /* If we're out of input, flush output and read more input. */ | ||
220 | if (in_index == read_chars) { | ||
221 | if (out_index) { | ||
222 | xwrite(STDOUT_FILENO, (char *)output, out_index); | ||
223 | out_index = 0; | ||
224 | } | ||
225 | read_chars = read(STDIN_FILENO, tr_buf, BUFSIZ); | ||
226 | if (read_chars <= 0) { | ||
227 | if (write(STDOUT_FILENO, (char *)output, out_index) != out_index) | ||
228 | bb_perror_msg(bb_msg_write_error); | ||
229 | exit(EXIT_SUCCESS); | ||
230 | } | ||
231 | in_index = 0; | ||
232 | } | ||
233 | c = tr_buf[in_index++]; | ||
234 | coded = vector[c]; | ||
235 | if ((flags & TR_OPT_delete) && invec[c]) | ||
236 | continue; | ||
237 | if ((flags & TR_OPT_squeeze_reps) && last == coded && | ||
238 | (invec[c] || outvec[coded])) | ||
239 | continue; | ||
240 | output[out_index++] = last = coded; | ||
241 | } | ||
242 | /* NOTREACHED */ | ||
254 | return EXIT_SUCCESS; | 243 | return EXIT_SUCCESS; |
255 | } | 244 | } |