diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-13 02:09:22 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-13 02:09:22 +0100 |
commit | aa42d13e320250d3573c6be975876a612c00e91f (patch) | |
tree | 822cacf0626690e608e15df32659c65caac29b36 /coreutils | |
parent | 31e2e7b86388e4ece09f37866bd1411f357cafbd (diff) | |
download | busybox-w32-aa42d13e320250d3573c6be975876a612c00e91f.tar.gz busybox-w32-aa42d13e320250d3573c6be975876a612c00e91f.tar.bz2 busybox-w32-aa42d13e320250d3573c6be975876a612c00e91f.zip |
sort: make sort -o FILE FILE (same FILE) work. Closes bug 785. -3 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/sort.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/coreutils/sort.c b/coreutils/sort.c index e2e7983a1..5c3fa1a71 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -278,27 +278,32 @@ static unsigned str2u(char **str) | |||
278 | int sort_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 278 | int sort_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
279 | int sort_main(int argc UNUSED_PARAM, char **argv) | 279 | int sort_main(int argc UNUSED_PARAM, char **argv) |
280 | { | 280 | { |
281 | FILE *fp, *outfile = stdout; | 281 | char *line, **lines; |
282 | char *line, **lines = NULL; | ||
283 | char *str_ignored, *str_o, *str_t; | 282 | char *str_ignored, *str_o, *str_t; |
284 | llist_t *lst_k = NULL; | 283 | llist_t *lst_k = NULL; |
285 | int i, flag; | 284 | int i, flag; |
286 | int linecount = 0; | 285 | int linecount; |
286 | unsigned opts; | ||
287 | 287 | ||
288 | xfunc_error_retval = 2; | 288 | xfunc_error_retval = 2; |
289 | 289 | ||
290 | /* Parse command line options */ | 290 | /* Parse command line options */ |
291 | /* -o and -t can be given at most once */ | 291 | /* -o and -t can be given at most once */ |
292 | opt_complementary = "o--o:t--t:" /* -t, -o: maximum one of each */ | 292 | opt_complementary = "o--o:t--t:" /* -t, -o: at most one of each */ |
293 | "k::"; /* -k takes list */ | 293 | "k::"; /* -k takes list */ |
294 | getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); | 294 | opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); |
295 | /* global b strips leading and trailing spaces */ | ||
296 | if (opts & FLAG_b) | ||
297 | option_mask32 |= FLAG_bb; | ||
295 | #if ENABLE_FEATURE_SORT_BIG | 298 | #if ENABLE_FEATURE_SORT_BIG |
296 | if (option_mask32 & FLAG_o) outfile = xfopen_for_write(str_o); | 299 | if (opts & FLAG_t) { |
297 | if (option_mask32 & FLAG_t) { | ||
298 | if (!str_t[0] || str_t[1]) | 300 | if (!str_t[0] || str_t[1]) |
299 | bb_error_msg_and_die("bad -t parameter"); | 301 | bb_error_msg_and_die("bad -t parameter"); |
300 | key_separator = str_t[0]; | 302 | key_separator = str_t[0]; |
301 | } | 303 | } |
304 | /* note: below this point we use option_mask32, not opts, | ||
305 | * since that reduces register pressure and makes code smaller */ | ||
306 | |||
302 | /* parse sort key */ | 307 | /* parse sort key */ |
303 | while (lst_k) { | 308 | while (lst_k) { |
304 | enum { | 309 | enum { |
@@ -315,7 +320,6 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
315 | }; | 320 | }; |
316 | struct sort_key *key = add_key(); | 321 | struct sort_key *key = add_key(); |
317 | char *str_k = llist_pop(&lst_k); | 322 | char *str_k = llist_pop(&lst_k); |
318 | const char *temp2; | ||
319 | 323 | ||
320 | i = 0; /* i==0 before comma, 1 after (-k3,6) */ | 324 | i = 0; /* i==0 before comma, 1 after (-k3,6) */ |
321 | while (*str_k) { | 325 | while (*str_k) { |
@@ -327,11 +331,13 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
327 | key->range[2*i+1] = str2u(&str_k); | 331 | key->range[2*i+1] = str2u(&str_k); |
328 | } | 332 | } |
329 | while (*str_k) { | 333 | while (*str_k) { |
334 | const char *temp2; | ||
335 | |||
330 | if (*str_k == ',' && !i++) { | 336 | if (*str_k == ',' && !i++) { |
331 | str_k++; | 337 | str_k++; |
332 | break; | 338 | break; |
333 | } /* no else needed: fall through to syntax error | 339 | } /* no else needed: fall through to syntax error |
334 | because comma isn't in OPT_STR */ | 340 | because comma isn't in OPT_STR */ |
335 | temp2 = strchr(OPT_STR, *str_k); | 341 | temp2 = strchr(OPT_STR, *str_k); |
336 | if (!temp2) | 342 | if (!temp2) |
337 | bb_error_msg_and_die("unknown key option"); | 343 | bb_error_msg_and_die("unknown key option"); |
@@ -339,27 +345,29 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
339 | if (flag & ~FLAG_allowed_for_k) | 345 | if (flag & ~FLAG_allowed_for_k) |
340 | bb_error_msg_and_die("unknown sort type"); | 346 | bb_error_msg_and_die("unknown sort type"); |
341 | /* b after ',' means strip _trailing_ space */ | 347 | /* b after ',' means strip _trailing_ space */ |
342 | if (i && flag == FLAG_b) flag = FLAG_bb; | 348 | if (i && flag == FLAG_b) |
349 | flag = FLAG_bb; | ||
343 | key->flags |= flag; | 350 | key->flags |= flag; |
344 | str_k++; | 351 | str_k++; |
345 | } | 352 | } |
346 | } | 353 | } |
347 | } | 354 | } |
348 | #endif | 355 | #endif |
349 | /* global b strips leading and trailing spaces */ | ||
350 | if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb; | ||
351 | 356 | ||
352 | /* Open input files and read data */ | 357 | /* Open input files and read data */ |
353 | argv += optind; | 358 | argv += optind; |
354 | if (!*argv) | 359 | if (!*argv) |
355 | *--argv = (char*)"-"; | 360 | *--argv = (char*)"-"; |
361 | linecount = 0; | ||
362 | lines = NULL; | ||
356 | do { | 363 | do { |
357 | /* coreutils 6.9 compat: abort on first open error, | 364 | /* coreutils 6.9 compat: abort on first open error, |
358 | * do not continue to next file: */ | 365 | * do not continue to next file: */ |
359 | fp = xfopen_stdin(*argv); | 366 | FILE *fp = xfopen_stdin(*argv); |
360 | for (;;) { | 367 | for (;;) { |
361 | line = GET_LINE(fp); | 368 | line = GET_LINE(fp); |
362 | if (!line) break; | 369 | if (!line) |
370 | break; | ||
363 | lines = xrealloc_vector(lines, 6, linecount); | 371 | lines = xrealloc_vector(lines, 6, linecount); |
364 | lines[linecount++] = line; | 372 | lines[linecount++] = line; |
365 | } | 373 | } |
@@ -373,16 +381,17 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
373 | /* handle -c */ | 381 | /* handle -c */ |
374 | if (option_mask32 & FLAG_c) { | 382 | if (option_mask32 & FLAG_c) { |
375 | int j = (option_mask32 & FLAG_u) ? -1 : 0; | 383 | int j = (option_mask32 & FLAG_u) ? -1 : 0; |
376 | for (i = 1; i < linecount; i++) | 384 | for (i = 1; i < linecount; i++) { |
377 | if (compare_keys(&lines[i-1], &lines[i]) > j) { | 385 | if (compare_keys(&lines[i-1], &lines[i]) > j) { |
378 | fprintf(stderr, "Check line %d\n", i); | 386 | fprintf(stderr, "Check line %u\n", i); |
379 | return EXIT_FAILURE; | 387 | return EXIT_FAILURE; |
380 | } | 388 | } |
389 | } | ||
381 | return EXIT_SUCCESS; | 390 | return EXIT_SUCCESS; |
382 | } | 391 | } |
383 | #endif | 392 | #endif |
384 | /* Perform the actual sort */ | 393 | /* Perform the actual sort */ |
385 | qsort(lines, linecount, sizeof(char *), compare_keys); | 394 | qsort(lines, linecount, sizeof(lines[0]), compare_keys); |
386 | /* handle -u */ | 395 | /* handle -u */ |
387 | if (option_mask32 & FLAG_u) { | 396 | if (option_mask32 & FLAG_u) { |
388 | flag = 0; | 397 | flag = 0; |
@@ -390,17 +399,24 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
390 | /* -- disabling last-resort compare... */ | 399 | /* -- disabling last-resort compare... */ |
391 | option_mask32 |= FLAG_s; | 400 | option_mask32 |= FLAG_s; |
392 | for (i = 1; i < linecount; i++) { | 401 | for (i = 1; i < linecount; i++) { |
393 | if (!compare_keys(&lines[flag], &lines[i])) | 402 | if (compare_keys(&lines[flag], &lines[i]) == 0) |
394 | free(lines[i]); | 403 | free(lines[i]); |
395 | else | 404 | else |
396 | lines[++flag] = lines[i]; | 405 | lines[++flag] = lines[i]; |
397 | } | 406 | } |
398 | if (linecount) linecount = flag+1; | 407 | if (linecount) |
408 | linecount = flag+1; | ||
399 | } | 409 | } |
410 | |||
400 | /* Print it */ | 411 | /* Print it */ |
412 | #if ENABLE_FEATURE_SORT_BIG | ||
413 | /* Open output file _after_ we read all input ones */ | ||
414 | if (option_mask32 & FLAG_o) | ||
415 | xmove_fd(xopen3(str_o, O_WRONLY, 0666), STDOUT_FILENO); | ||
416 | #endif | ||
401 | flag = (option_mask32 & FLAG_z) ? '\0' : '\n'; | 417 | flag = (option_mask32 & FLAG_z) ? '\0' : '\n'; |
402 | for (i = 0; i < linecount; i++) | 418 | for (i = 0; i < linecount; i++) |
403 | fprintf(outfile, "%s%c", lines[i], flag); | 419 | printf("%s%c", lines[i], flag); |
404 | 420 | ||
405 | fflush_stdout_and_exit(EXIT_SUCCESS); | 421 | fflush_stdout_and_exit(EXIT_SUCCESS); |
406 | } | 422 | } |