Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/uniq.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/uniq.c
r1765 r2725 5 5 * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 … … 13 13 #include "libbb.h" 14 14 15 static const char uniq_opts[] ALIGN1 = "cdu" "f:s:" "cdu\0\1\2\4"; 16 17 static FILE *xgetoptfile_uniq_s(char **argv, int read0write2) 15 int uniq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 16 int uniq_main(int argc UNUSED_PARAM, char **argv) 18 17 { 19 const char *n; 20 21 n = *argv; 22 if (n != NULL) { 23 if ((*n != '-') || n[1]) { 24 return xfopen(n, "r\0w" + read0write2); 25 } 26 } 27 return (read0write2) ? stdout : stdin; 28 } 29 30 int uniq_main(int argc, char **argv); 31 int uniq_main(int argc, char **argv) 32 { 33 FILE *in, *out; 34 unsigned long dups, skip_fields, skip_chars, i; 35 const char *s0, *e0, *s1, *e1, *input_filename; 18 const char *input_filename; 19 unsigned skip_fields, skip_chars, max_chars; 36 20 unsigned opt; 21 char *cur_line; 22 const char *cur_compare; 37 23 38 24 enum { 39 25 OPT_c = 0x1, 40 OPT_d = 0x2, 41 OPT_u = 0x4, 26 OPT_d = 0x2, /* print only dups */ 27 OPT_u = 0x4, /* print only uniq */ 42 28 OPT_f = 0x8, 43 29 OPT_s = 0x10, 30 OPT_w = 0x20, 44 31 }; 45 32 46 33 skip_fields = skip_chars = 0; 34 max_chars = INT_MAX; 47 35 48 opt = getopt32(argv, "cduf:s:", &s0, &s1); 49 if (opt & OPT_f) 50 skip_fields = xatoul(s0); 51 if (opt & OPT_s) 52 skip_chars = xatoul(s1); 36 opt_complementary = "f+:s+:w+"; 37 opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars); 53 38 argv += optind; 54 39 55 input_filename = *argv; 40 input_filename = argv[0]; 41 if (input_filename) { 42 const char *output; 56 43 57 in = xgetoptfile_uniq_s(argv, 0); 58 if (*argv) { 59 ++argv; 60 } 61 out = xgetoptfile_uniq_s(argv, 2); 62 if (*argv && argv[1]) { 63 bb_show_usage(); 44 if (input_filename[0] != '-' || input_filename[1]) { 45 close(STDIN_FILENO); /* == 0 */ 46 xopen(input_filename, O_RDONLY); /* fd will be 0 */ 47 } 48 output = argv[1]; 49 if (output) { 50 if (argv[2]) 51 bb_show_usage(); 52 if (output[0] != '-' || output[1]) { 53 // Won't work with "uniq - FILE" and closed stdin: 54 //close(STDOUT_FILENO); 55 //xopen(output, O_WRONLY | O_CREAT | O_TRUNC); 56 xmove_fd(xopen(output, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO); 57 } 58 } 64 59 } 65 60 66 s1 = e1 = NULL;/* prime the pump */61 cur_compare = cur_line = NULL; /* prime the pump */ 67 62 68 63 do { 69 s0 = s1; 70 e0 = e1; 64 unsigned i; 65 unsigned long dups; 66 char *old_line; 67 const char *old_compare; 68 69 old_line = cur_line; 70 old_compare = cur_compare; 71 71 dups = 0; 72 72 73 73 /* gnu uniq ignores newlines */ 74 while (( s1 = xmalloc_getline(in)) != NULL) {75 e1 = s1;74 while ((cur_line = xmalloc_fgetline(stdin)) != NULL) { 75 cur_compare = cur_line; 76 76 for (i = skip_fields; i; i--) { 77 e1 = skip_whitespace(e1);78 e1 = skip_non_whitespace(e1);77 cur_compare = skip_whitespace(cur_compare); 78 cur_compare = skip_non_whitespace(cur_compare); 79 79 } 80 for (i = skip_chars; * e1&& i; i--) {81 ++ e1;80 for (i = skip_chars; *cur_compare && i; i--) { 81 ++cur_compare; 82 82 } 83 83 84 if (! s0 || strcmp(e0, e1)) {84 if (!old_line || strncmp(old_compare, cur_compare, max_chars)) { 85 85 break; 86 86 } 87 87 88 ++dups; /* Note: Testing for overflow seems excessive. */ 88 free(cur_line); 89 ++dups; /* testing for overflow seems excessive */ 89 90 } 90 91 91 if (s0) { 92 if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_e) */ 93 fprintf(out, "\0%d " + (opt & 1), dups + 1); 94 fprintf(out, "%s\n", s0); 92 if (old_line) { 93 if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_u) */ 94 if (opt & OPT_c) { 95 /* %7lu matches GNU coreutils 6.9 */ 96 printf("%7lu ", dups + 1); 97 } 98 printf("%s\n", old_line); 95 99 } 96 free( (void *)s0);100 free(old_line); 97 101 } 98 } while ( s1);102 } while (cur_line); 99 103 100 die_if_ferror( in, input_filename);104 die_if_ferror(stdin, input_filename); 101 105 102 106 fflush_stdout_and_exit(EXIT_SUCCESS);
Note:
See TracChangeset
for help on using the changeset viewer.