aboutsummaryrefslogtreecommitdiff
path: root/coreutils/tr.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-04 10:16:52 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-04 10:16:52 +0000
commit74324c86663f57a19c1de303ee8c8e5449db9ef2 (patch)
tree11f5da9de4212875ce5811be2e1050e076378c9a /coreutils/tr.c
parent4e5f82c76f08614d0b69f9ec4a8baac303af15f6 (diff)
downloadbusybox-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.c87
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 */
30static char *poutput, *pvector, *pinvec, *poutvec;
31 28
32static void ATTRIBUTE_NORETURN convert(const smalluint flags) 29static 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
62static 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
184static int complement(char *buffer, int buffer_len) 152static 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}