source: MondoRescue/branches/3.3/mindi-busybox/coreutils/uniq.c@ 3647

Last change on this file since 3647 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 3.1 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * uniq implementation for busybox
4 *
5 * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org>
6 *
[2725]7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
[821]8 */
9
10/* BB_AUDIT SUSv3 compliant */
11/* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */
12
[3232]13//usage:#define uniq_trivial_usage
14//usage: "[-cdu][-f,s,w N] [INPUT [OUTPUT]]"
15//usage:#define uniq_full_usage "\n\n"
16//usage: "Discard duplicate lines\n"
17//usage: "\n -c Prefix lines by the number of occurrences"
18//usage: "\n -d Only print duplicate lines"
19//usage: "\n -u Only print unique lines"
20//usage: "\n -f N Skip first N fields"
21//usage: "\n -s N Skip first N chars (after any skipped fields)"
22//usage: "\n -w N Compare N characters in line"
23//usage:
24//usage:#define uniq_example_usage
25//usage: "$ echo -e \"a\\na\\nb\\nc\\nc\\na\" | sort | uniq\n"
26//usage: "a\n"
27//usage: "b\n"
28//usage: "c\n"
29
[1765]30#include "libbb.h"
[821]31
[2725]32int uniq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
33int uniq_main(int argc UNUSED_PARAM, char **argv)
[821]34{
[2725]35 const char *input_filename;
36 unsigned skip_fields, skip_chars, max_chars;
[1765]37 unsigned opt;
[2725]38 char *cur_line;
39 const char *cur_compare;
[821]40
[1765]41 enum {
42 OPT_c = 0x1,
[2725]43 OPT_d = 0x2, /* print only dups */
44 OPT_u = 0x4, /* print only uniq */
[1765]45 OPT_f = 0x8,
46 OPT_s = 0x10,
[2725]47 OPT_w = 0x20,
[1765]48 };
[821]49
[1765]50 skip_fields = skip_chars = 0;
[2725]51 max_chars = INT_MAX;
[821]52
[2725]53 opt_complementary = "f+:s+:w+";
54 opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars);
[1765]55 argv += optind;
[821]56
[2725]57 input_filename = argv[0];
58 if (input_filename) {
59 const char *output;
[1765]60
[2725]61 if (input_filename[0] != '-' || input_filename[1]) {
62 close(STDIN_FILENO); /* == 0 */
63 xopen(input_filename, O_RDONLY); /* fd will be 0 */
64 }
65 output = argv[1];
66 if (output) {
67 if (argv[2])
68 bb_show_usage();
69 if (output[0] != '-' || output[1]) {
70 // Won't work with "uniq - FILE" and closed stdin:
71 //close(STDOUT_FILENO);
72 //xopen(output, O_WRONLY | O_CREAT | O_TRUNC);
73 xmove_fd(xopen(output, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
74 }
75 }
[821]76 }
77
[2725]78 cur_compare = cur_line = NULL; /* prime the pump */
[821]79
80 do {
[2725]81 unsigned i;
82 unsigned long dups;
83 char *old_line;
84 const char *old_compare;
85
86 old_line = cur_line;
87 old_compare = cur_compare;
[821]88 dups = 0;
89
90 /* gnu uniq ignores newlines */
[2725]91 while ((cur_line = xmalloc_fgetline(stdin)) != NULL) {
92 cur_compare = cur_line;
[1765]93 for (i = skip_fields; i; i--) {
[2725]94 cur_compare = skip_whitespace(cur_compare);
95 cur_compare = skip_non_whitespace(cur_compare);
[821]96 }
[2725]97 for (i = skip_chars; *cur_compare && i; i--) {
98 ++cur_compare;
[821]99 }
100
[2725]101 if (!old_line || strncmp(old_compare, cur_compare, max_chars)) {
[821]102 break;
103 }
104
[2725]105 free(cur_line);
106 ++dups; /* testing for overflow seems excessive */
[821]107 }
108
[2725]109 if (old_line) {
110 if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_u) */
111 if (opt & OPT_c) {
112 /* %7lu matches GNU coreutils 6.9 */
113 printf("%7lu ", dups + 1);
114 }
[3621]115 puts(old_line);
[821]116 }
[2725]117 free(old_line);
[821]118 }
[2725]119 } while (cur_line);
[821]120
[2725]121 die_if_ferror(stdin, input_filename);
[821]122
[1765]123 fflush_stdout_and_exit(EXIT_SUCCESS);
[821]124}
Note: See TracBrowser for help on using the repository browser.