1 /* vi: set sw=4 ts=4: */
3 * uniq implementation for busybox
5 * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10 /* BB_AUDIT SUSv3 compliant */
11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */
15 int uniq_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
16 int uniq_main(int argc UNUSED_PARAM
, char **argv
)
18 const char *input_filename
;
19 unsigned skip_fields
, skip_chars
, max_chars
;
22 const char *cur_compare
;
26 OPT_d
= 0x2, /* print only dups */
27 OPT_u
= 0x4, /* print only uniq */
33 skip_fields
= skip_chars
= 0;
36 opt_complementary
= "f+:s+:w+";
37 opt
= getopt32(argv
, "cduf:s:w:", &skip_fields
, &skip_chars
, &max_chars
);
40 input_filename
= argv
[0];
44 if (input_filename
[0] != '-' || input_filename
[1]) {
45 close(STDIN_FILENO
); /* == 0 */
46 xopen(input_filename
, O_RDONLY
); /* fd will be 0 */
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
);
61 cur_compare
= cur_line
= NULL
; /* prime the pump */
67 const char *old_compare
;
70 old_compare
= cur_compare
;
73 /* gnu uniq ignores newlines */
74 while ((cur_line
= xmalloc_fgetline(stdin
)) != NULL
) {
75 cur_compare
= cur_line
;
76 for (i
= skip_fields
; i
; i
--) {
77 cur_compare
= skip_whitespace(cur_compare
);
78 cur_compare
= skip_non_whitespace(cur_compare
);
80 for (i
= skip_chars
; *cur_compare
&& i
; i
--) {
84 if (!old_line
|| strncmp(old_compare
, cur_compare
, max_chars
)) {
89 ++dups
; /* testing for overflow seems excessive */
93 if (!(opt
& (OPT_d
<< !!dups
))) { /* (if dups, opt & OPT_u) */
95 /* %7lu matches GNU coreutils 6.9 */
96 printf("%7lu ", dups
+ 1);
98 printf("%s\n", old_line
);
104 die_if_ferror(stdin
, input_filename
);
106 fflush_stdout_and_exit(EXIT_SUCCESS
);