diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-22 10:34:46 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-22 10:34:46 +0000 |
commit | 9e3a540b1beb135ff446731209cb35a78854ee88 (patch) | |
tree | 3ec5032293faf7d110dbd0a1bd214aebf398507a /coreutils | |
parent | a5254032f57627fa3b9b9acebc6bdd0a6e02955f (diff) | |
download | busybox-w32-9e3a540b1beb135ff446731209cb35a78854ee88.tar.gz busybox-w32-9e3a540b1beb135ff446731209cb35a78854ee88.tar.bz2 busybox-w32-9e3a540b1beb135ff446731209cb35a78854ee88.zip |
cut: stop using static data. This alone removed ~70 bytes of code.
+ some optimizations
function old new delta
nlists 4 - -4
cut_lists 4 - -4
cut_main 1041 960 -81
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/cut.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/coreutils/cut.c b/coreutils/cut.c index 3bac151b2..0d95ff84f 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -33,11 +33,6 @@ enum { | |||
33 | NON_RANGE = -1 | 33 | NON_RANGE = -1 |
34 | }; | 34 | }; |
35 | 35 | ||
36 | /* growable array holding a series of lists */ | ||
37 | static struct cut_list *cut_lists; | ||
38 | static unsigned int nlists; /* number of elements in above list */ | ||
39 | |||
40 | |||
41 | static int cmpfunc(const void *a, const void *b) | 36 | static int cmpfunc(const void *a, const void *b) |
42 | { | 37 | { |
43 | return (((struct cut_list *) a)->startpos - | 38 | return (((struct cut_list *) a)->startpos - |
@@ -45,18 +40,19 @@ static int cmpfunc(const void *a, const void *b) | |||
45 | 40 | ||
46 | } | 41 | } |
47 | 42 | ||
48 | static void cut_file(FILE *file, char delim) | 43 | static void cut_file(FILE *file, char delim, const struct cut_list *cut_lists, unsigned nlists) |
49 | { | 44 | { |
50 | char *line = NULL; | 45 | char *line; |
51 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ | 46 | unsigned linenum = 0; /* keep these zero-based to be consistent */ |
52 | 47 | ||
53 | /* go through every line in the file */ | 48 | /* go through every line in the file */ |
54 | while ((line = xmalloc_fgetline(file)) != NULL) { | 49 | while ((line = xmalloc_fgetline(file)) != NULL) { |
55 | 50 | ||
56 | /* set up a list so we can keep track of what's been printed */ | 51 | /* set up a list so we can keep track of what's been printed */ |
57 | char * printed = xzalloc(strlen(line) * sizeof(char)); | 52 | int linelen = strlen(line); |
58 | char * orig_line = line; | 53 | char *printed = xzalloc(linelen * sizeof(char)); |
59 | unsigned int cl_pos = 0; | 54 | char *orig_line = line; |
55 | unsigned cl_pos = 0; | ||
60 | int spos; | 56 | int spos; |
61 | 57 | ||
62 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ | 58 | /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ |
@@ -64,15 +60,19 @@ static void cut_file(FILE *file, char delim) | |||
64 | /* print the chars specified in each cut list */ | 60 | /* print the chars specified in each cut list */ |
65 | for (; cl_pos < nlists; cl_pos++) { | 61 | for (; cl_pos < nlists; cl_pos++) { |
66 | spos = cut_lists[cl_pos].startpos; | 62 | spos = cut_lists[cl_pos].startpos; |
67 | while (spos < (int)strlen(line)) { | 63 | while (spos < linelen) { |
68 | if (!printed[spos]) { | 64 | if (!printed[spos]) { |
69 | printed[spos] = 'X'; | 65 | printed[spos] = 'X'; |
70 | putchar(line[spos]); | 66 | putchar(line[spos]); |
71 | } | 67 | } |
72 | spos++; | 68 | spos++; |
73 | if (spos > cut_lists[cl_pos].endpos | 69 | if (spos > cut_lists[cl_pos].endpos |
74 | || cut_lists[cl_pos].endpos == NON_RANGE) | 70 | /* NON_RANGE is -1, so if below is true, |
71 | * the above was true too (spos is >= 0) */ | ||
72 | /* || cut_lists[cl_pos].endpos == NON_RANGE */ | ||
73 | ) { | ||
75 | break; | 74 | break; |
75 | } | ||
76 | } | 76 | } |
77 | } | 77 | } |
78 | } else if (delim == '\n') { /* cut by lines */ | 78 | } else if (delim == '\n') { /* cut by lines */ |
@@ -89,7 +89,8 @@ static void cut_file(FILE *file, char delim) | |||
89 | spos++; | 89 | spos++; |
90 | /* go to the next list if we're at the end of this one */ | 90 | /* go to the next list if we're at the end of this one */ |
91 | if (spos > cut_lists[cl_pos].endpos | 91 | if (spos > cut_lists[cl_pos].endpos |
92 | || cut_lists[cl_pos].endpos == NON_RANGE) { | 92 | || cut_lists[cl_pos].endpos == NON_RANGE |
93 | ) { | ||
93 | cl_pos++; | 94 | cl_pos++; |
94 | /* get out if there's no more lists to process */ | 95 | /* get out if there's no more lists to process */ |
95 | if (cl_pos >= nlists) | 96 | if (cl_pos >= nlists) |
@@ -148,7 +149,7 @@ static void cut_file(FILE *file, char delim) | |||
148 | * this is a list, and we're not at the end of that | 149 | * this is a list, and we're not at the end of that |
149 | * list */ | 150 | * list */ |
150 | } while (spos <= cut_lists[cl_pos].endpos && line | 151 | } while (spos <= cut_lists[cl_pos].endpos && line |
151 | && cut_lists[cl_pos].endpos != NON_RANGE); | 152 | && cut_lists[cl_pos].endpos != NON_RANGE); |
152 | } | 153 | } |
153 | } | 154 | } |
154 | /* if we printed anything at all, we need to finish it with a | 155 | /* if we printed anything at all, we need to finish it with a |
@@ -164,17 +165,21 @@ static void cut_file(FILE *file, char delim) | |||
164 | int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 165 | int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
165 | int cut_main(int argc UNUSED_PARAM, char **argv) | 166 | int cut_main(int argc UNUSED_PARAM, char **argv) |
166 | { | 167 | { |
168 | /* growable array holding a series of lists */ | ||
169 | struct cut_list *cut_lists = NULL; | ||
170 | unsigned nlists = 0; /* number of elements in above list */ | ||
167 | char delim = '\t'; /* delimiter, default is tab */ | 171 | char delim = '\t'; /* delimiter, default is tab */ |
168 | char *sopt, *ltok; | 172 | char *sopt, *ltok; |
173 | unsigned opt; | ||
169 | 174 | ||
170 | opt_complementary = "b--bcf:c--bcf:f--bcf"; | 175 | opt_complementary = "b--bcf:c--bcf:f--bcf"; |
171 | getopt32(argv, optstring, &sopt, &sopt, &sopt, <ok); | 176 | opt = getopt32(argv, optstring, &sopt, &sopt, &sopt, <ok); |
172 | // argc -= optind; | 177 | // argc -= optind; |
173 | argv += optind; | 178 | argv += optind; |
174 | if (!(option_mask32 & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) | 179 | if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) |
175 | bb_error_msg_and_die("expected a list of bytes, characters, or fields"); | 180 | bb_error_msg_and_die("expected a list of bytes, characters, or fields"); |
176 | 181 | ||
177 | if (option_mask32 & CUT_OPT_DELIM_FLGS) { | 182 | if (opt & CUT_OPT_DELIM_FLGS) { |
178 | if (ltok[0] && ltok[1]) { /* more than 1 char? */ | 183 | if (ltok[0] && ltok[1]) { /* more than 1 char? */ |
179 | bb_error_msg_and_die("the delimiter must be a single character"); | 184 | bb_error_msg_and_die("the delimiter must be a single character"); |
180 | } | 185 | } |
@@ -182,10 +187,10 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
182 | } | 187 | } |
183 | 188 | ||
184 | /* non-field (char or byte) cutting has some special handling */ | 189 | /* non-field (char or byte) cutting has some special handling */ |
185 | if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) { | 190 | if (!(opt & CUT_OPT_FIELDS_FLGS)) { |
186 | static const char _op_on_field[] ALIGN1 = " only when operating on fields"; | 191 | static const char _op_on_field[] ALIGN1 = " only when operating on fields"; |
187 | 192 | ||
188 | if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) { | 193 | if (opt & CUT_OPT_SUPPRESS_FLGS) { |
189 | bb_error_msg_and_die | 194 | bb_error_msg_and_die |
190 | ("suppressing non-delimited lines makes sense%s", | 195 | ("suppressing non-delimited lines makes sense%s", |
191 | _op_on_field); | 196 | _op_on_field); |
@@ -231,8 +236,8 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
231 | e = EOL; | 236 | e = EOL; |
232 | } else { | 237 | } else { |
233 | e = xatoi_u(ltok); | 238 | e = xatoi_u(ltok); |
234 | /* if the user specified and end position of 0, that means "til the | 239 | /* if the user specified and end position of 0, |
235 | * end of the line */ | 240 | * that means "til the end of the line" */ |
236 | if (e == 0) | 241 | if (e == 0) |
237 | e = EOL; | 242 | e = EOL; |
238 | e--; /* again, arrays are zero based, lines are 1 based */ | 243 | e--; /* again, arrays are zero based, lines are 1 based */ |
@@ -242,6 +247,8 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
242 | 247 | ||
243 | /* add the new list */ | 248 | /* add the new list */ |
244 | cut_lists = xrealloc_vector(cut_lists, 4, nlists); | 249 | cut_lists = xrealloc_vector(cut_lists, 4, nlists); |
250 | /* NB: startpos is always >= 0, | ||
251 | * while endpos may be = NON_RANGE (-1) */ | ||
245 | cut_lists[nlists].startpos = s; | 252 | cut_lists[nlists].startpos = s; |
246 | cut_lists[nlists].endpos = e; | 253 | cut_lists[nlists].endpos = e; |
247 | nlists++; | 254 | nlists++; |
@@ -269,7 +276,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
269 | retval = EXIT_FAILURE; | 276 | retval = EXIT_FAILURE; |
270 | continue; | 277 | continue; |
271 | } | 278 | } |
272 | cut_file(file, delim); | 279 | cut_file(file, delim, cut_lists, nlists); |
273 | fclose_if_not_stdin(file); | 280 | fclose_if_not_stdin(file); |
274 | } while (*++argv); | 281 | } while (*++argv); |
275 | 282 | ||