diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-23 07:26:15 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-23 07:26:15 +0000 |
commit | 3831c91c95116b9a9b28f67e998e53a80b3e33bd (patch) | |
tree | 620270a18eaa0dac06b7904acee5156709c9e215 /coreutils | |
parent | e85dbae3896eaf26a591a34bc5e827f55ea8e041 (diff) | |
download | busybox-w32-3831c91c95116b9a9b28f67e998e53a80b3e33bd.tar.gz busybox-w32-3831c91c95116b9a9b28f67e998e53a80b3e33bd.tar.bz2 busybox-w32-3831c91c95116b9a9b28f67e998e53a80b3e33bd.zip |
cut: add proper stdout error handling, fix "-" handling;
modest code shrink
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/cut.c | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/coreutils/cut.c b/coreutils/cut.c index 257f3d649..4f0bed3e7 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -16,13 +16,11 @@ | |||
16 | 16 | ||
17 | /* option vars */ | 17 | /* option vars */ |
18 | static const char optstring[] ALIGN1 = "b:c:f:d:sn"; | 18 | static const char optstring[] ALIGN1 = "b:c:f:d:sn"; |
19 | #define CUT_OPT_BYTE_FLGS (1<<0) | 19 | #define CUT_OPT_BYTE_FLGS (1 << 0) |
20 | #define CUT_OPT_CHAR_FLGS (1<<1) | 20 | #define CUT_OPT_CHAR_FLGS (1 << 1) |
21 | #define CUT_OPT_FIELDS_FLGS (1<<2) | 21 | #define CUT_OPT_FIELDS_FLGS (1 << 2) |
22 | #define CUT_OPT_DELIM_FLGS (1<<3) | 22 | #define CUT_OPT_DELIM_FLGS (1 << 3) |
23 | #define CUT_OPT_SUPPRESS_FLGS (1<<4) | 23 | #define CUT_OPT_SUPPRESS_FLGS (1 << 4) |
24 | |||
25 | static char delim = '\t'; /* delimiter, default is tab */ | ||
26 | 24 | ||
27 | struct cut_list { | 25 | struct cut_list { |
28 | int startpos; | 26 | int startpos; |
@@ -47,7 +45,7 @@ static int cmpfunc(const void *a, const void *b) | |||
47 | 45 | ||
48 | } | 46 | } |
49 | 47 | ||
50 | static void cut_file(FILE * file) | 48 | static void cut_file(FILE *file, char delim) |
51 | { | 49 | { |
52 | char *line = NULL; | 50 | char *line = NULL; |
53 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ | 51 | unsigned int linenum = 0; /* keep these zero-based to be consistent */ |
@@ -163,11 +161,10 @@ static void cut_file(FILE * file) | |||
163 | } | 161 | } |
164 | } | 162 | } |
165 | 163 | ||
166 | static const char _op_on_field[] ALIGN1 = " only when operating on fields"; | ||
167 | |||
168 | int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 164 | int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
169 | int cut_main(int argc, char **argv) | 165 | int cut_main(int argc, char **argv) |
170 | { | 166 | { |
167 | char delim = '\t'; /* delimiter, default is tab */ | ||
171 | char *sopt, *ltok; | 168 | char *sopt, *ltok; |
172 | 169 | ||
173 | opt_complementary = "b--bcf:c--bcf:f--bcf"; | 170 | opt_complementary = "b--bcf:c--bcf:f--bcf"; |
@@ -178,7 +175,7 @@ int cut_main(int argc, char **argv) | |||
178 | bb_error_msg_and_die("expected a list of bytes, characters, or fields"); | 175 | bb_error_msg_and_die("expected a list of bytes, characters, or fields"); |
179 | 176 | ||
180 | if (option_mask32 & CUT_OPT_DELIM_FLGS) { | 177 | if (option_mask32 & CUT_OPT_DELIM_FLGS) { |
181 | if (strlen(ltok) > 1) { | 178 | if (ltok[0] && ltok[1]) { /* more than 1 char? */ |
182 | bb_error_msg_and_die("the delimiter must be a single character"); | 179 | bb_error_msg_and_die("the delimiter must be a single character"); |
183 | } | 180 | } |
184 | delim = ltok[0]; | 181 | delim = ltok[0]; |
@@ -186,6 +183,8 @@ int cut_main(int argc, char **argv) | |||
186 | 183 | ||
187 | /* non-field (char or byte) cutting has some special handling */ | 184 | /* non-field (char or byte) cutting has some special handling */ |
188 | if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) { | 185 | if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) { |
186 | static const char _op_on_field[] ALIGN1 = " only when operating on fields"; | ||
187 | |||
189 | if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) { | 188 | if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) { |
190 | bb_error_msg_and_die | 189 | bb_error_msg_and_die |
191 | ("suppressing non-delimited lines makes sense%s", | 190 | ("suppressing non-delimited lines makes sense%s", |
@@ -210,15 +209,12 @@ int cut_main(int argc, char **argv) | |||
210 | while ((ltok = strsep(&sopt, ",")) != NULL) { | 209 | while ((ltok = strsep(&sopt, ",")) != NULL) { |
211 | 210 | ||
212 | /* it's actually legal to pass an empty list */ | 211 | /* it's actually legal to pass an empty list */ |
213 | if (strlen(ltok) == 0) | 212 | if (!ltok[0]) |
214 | continue; | 213 | continue; |
215 | 214 | ||
216 | /* get the start pos */ | 215 | /* get the start pos */ |
217 | ntok = strsep(<ok, "-"); | 216 | ntok = strsep(<ok, "-"); |
218 | if (ntok == NULL) { | 217 | if (!ntok[0]) { |
219 | bb_error_msg | ||
220 | ("internal error: ntok is null for start pos!?\n"); | ||
221 | } else if (strlen(ntok) == 0) { | ||
222 | s = BOL; | 218 | s = BOL; |
223 | } else { | 219 | } else { |
224 | s = xatoi_u(ntok); | 220 | s = xatoi_u(ntok); |
@@ -229,13 +225,12 @@ int cut_main(int argc, char **argv) | |||
229 | } | 225 | } |
230 | 226 | ||
231 | /* get the end pos */ | 227 | /* get the end pos */ |
232 | ntok = strsep(<ok, "-"); | 228 | if (ltok == NULL) { |
233 | if (ntok == NULL) { | ||
234 | e = NON_RANGE; | 229 | e = NON_RANGE; |
235 | } else if (strlen(ntok) == 0) { | 230 | } else if (!ltok[0]) { |
236 | e = EOL; | 231 | e = EOL; |
237 | } else { | 232 | } else { |
238 | e = xatoi_u(ntok); | 233 | e = xatoi_u(ltok); |
239 | /* if the user specified and end position of 0, that means "til the | 234 | /* if the user specified and end position of 0, that means "til the |
240 | * end of the line */ | 235 | * end of the line */ |
241 | if (e == 0) | 236 | if (e == 0) |
@@ -245,11 +240,6 @@ int cut_main(int argc, char **argv) | |||
245 | e = NON_RANGE; | 240 | e = NON_RANGE; |
246 | } | 241 | } |
247 | 242 | ||
248 | /* if there's something left to tokenize, the user passed | ||
249 | * an invalid list */ | ||
250 | if (ltok) | ||
251 | bb_error_msg_and_die("invalid byte or field list"); | ||
252 | |||
253 | /* add the new list */ | 243 | /* add the new list */ |
254 | cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); | 244 | cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); |
255 | cut_lists[nlists-1].startpos = s; | 245 | cut_lists[nlists-1].startpos = s; |
@@ -266,23 +256,31 @@ int cut_main(int argc, char **argv) | |||
266 | qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); | 256 | qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); |
267 | } | 257 | } |
268 | 258 | ||
269 | /* argv[0..argc-1] should be names of file to process. If no | 259 | { |
270 | * files were specified or '-' was specified, take input from stdin. | 260 | int retval = EXIT_SUCCESS; |
271 | * Otherwise, we process all the files specified. */ | 261 | FILE *file = stdin; |
272 | if (argv[0] == NULL || LONE_DASH(argv[0])) { | 262 | |
273 | cut_file(stdin); | 263 | if (!*argv) { |
274 | } else { | 264 | argv--; |
275 | FILE *file; | 265 | goto jump_in; |
266 | } | ||
276 | 267 | ||
277 | do { | 268 | do { |
278 | file = fopen_or_warn(argv[0], "r"); | 269 | file = stdin; |
279 | if (file) { | 270 | if (NOT_LONE_DASH(*argv)) |
280 | cut_file(file); | 271 | file = fopen_or_warn(*argv, "r"); |
281 | fclose(file); | 272 | if (!file) { |
273 | retval = EXIT_FAILURE; | ||
274 | continue; | ||
282 | } | 275 | } |
276 | jump_in: | ||
277 | cut_file(file, delim); | ||
278 | if (NOT_LONE_DASH(*argv)) | ||
279 | fclose(file); | ||
283 | } while (*++argv); | 280 | } while (*++argv); |
281 | |||
282 | if (ENABLE_FEATURE_CLEAN_UP) | ||
283 | free(cut_lists); | ||
284 | fflush_stdout_and_exit(retval); | ||
284 | } | 285 | } |
285 | if (ENABLE_FEATURE_CLEAN_UP) | ||
286 | free(cut_lists); | ||
287 | return EXIT_SUCCESS; | ||
288 | } | 286 | } |