source: MondoRescue/branches/2.2.5/mindi-busybox/coreutils/uniq.c@ 1765

Last change on this file since 1765 was 1765, checked in by Bruno Cornec, 16 years ago

Update to busybox 1.7.2

File size: 2.0 KB
Line 
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 *
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8 */
9
10/* BB_AUDIT SUSv3 compliant */
11/* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */
12
13#include "libbb.h"
14
15static const char uniq_opts[] ALIGN1 = "cdu" "f:s:" "cdu\0\1\2\4";
16
17static FILE *xgetoptfile_uniq_s(char **argv, int read0write2)
18{
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
30int uniq_main(int argc, char **argv);
31int 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;
36 unsigned opt;
37
38 enum {
39 OPT_c = 0x1,
40 OPT_d = 0x2,
41 OPT_u = 0x4,
42 OPT_f = 0x8,
43 OPT_s = 0x10,
44 };
45
46 skip_fields = skip_chars = 0;
47
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);
53 argv += optind;
54
55 input_filename = *argv;
56
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();
64 }
65
66 s1 = e1 = NULL; /* prime the pump */
67
68 do {
69 s0 = s1;
70 e0 = e1;
71 dups = 0;
72
73 /* gnu uniq ignores newlines */
74 while ((s1 = xmalloc_getline(in)) != NULL) {
75 e1 = s1;
76 for (i = skip_fields; i; i--) {
77 e1 = skip_whitespace(e1);
78 e1 = skip_non_whitespace(e1);
79 }
80 for (i = skip_chars; *e1 && i; i--) {
81 ++e1;
82 }
83
84 if (!s0 || strcmp(e0, e1)) {
85 break;
86 }
87
88 ++dups; /* Note: Testing for overflow seems excessive. */
89 }
90
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);
95 }
96 free((void *)s0);
97 }
98 } while (s1);
99
100 die_if_ferror(in, input_filename);
101
102 fflush_stdout_and_exit(EXIT_SUCCESS);
103}
Note: See TracBrowser for help on using the repository browser.