aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-23 07:26:15 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-23 07:26:15 +0000
commit3831c91c95116b9a9b28f67e998e53a80b3e33bd (patch)
tree620270a18eaa0dac06b7904acee5156709c9e215 /coreutils
parente85dbae3896eaf26a591a34bc5e827f55ea8e041 (diff)
downloadbusybox-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.c76
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 */
18static const char optstring[] ALIGN1 = "b:c:f:d:sn"; 18static 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
25static char delim = '\t'; /* delimiter, default is tab */
26 24
27struct cut_list { 25struct 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
50static void cut_file(FILE * file) 48static 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
166static const char _op_on_field[] ALIGN1 = " only when operating on fields";
167
168int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 164int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
169int cut_main(int argc, char **argv) 165int 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(&ltok, "-"); 216 ntok = strsep(&ltok, "-");
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(&ltok, "-"); 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}