Magellan Linux

Contents of /trunk/mkinitrd-magellan/busybox/coreutils/uniq.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (show annotations) (download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 2059 byte(s)
-updated to busybox-1.13.4
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
15 static FILE *xgetoptfile_uniq_s(char **argv, int read0write2)
16 {
17 const char *n;
18
19 n = *argv;
20 if (n != NULL) {
21 if ((*n != '-') || n[1]) {
22 return xfopen(n, "r\0w" + read0write2);
23 }
24 }
25 return (read0write2) ? stdout : stdin;
26 }
27
28 int uniq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
29 int uniq_main(int argc UNUSED_PARAM, char **argv)
30 {
31 FILE *in, *out;
32 const char *s0, *e0, *s1, *e1, *input_filename;
33 unsigned long dups;
34 unsigned skip_fields, skip_chars, max_chars;
35 unsigned opt;
36 unsigned i;
37
38 enum {
39 OPT_c = 0x1,
40 OPT_d = 0x2,
41 OPT_u = 0x4,
42 OPT_f = 0x8,
43 OPT_s = 0x10,
44 OPT_w = 0x20,
45 };
46
47 skip_fields = skip_chars = 0;
48 max_chars = -1;
49
50 opt_complementary = "f+:s+:w+";
51 opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars);
52 argv += optind;
53
54 input_filename = *argv;
55
56 in = xgetoptfile_uniq_s(argv, 0);
57 if (*argv) {
58 ++argv;
59 }
60 out = xgetoptfile_uniq_s(argv, 2);
61 if (*argv && argv[1]) {
62 bb_show_usage();
63 }
64
65 s1 = e1 = NULL; /* prime the pump */
66
67 do {
68 s0 = s1;
69 e0 = e1;
70 dups = 0;
71
72 /* gnu uniq ignores newlines */
73 while ((s1 = xmalloc_fgetline(in)) != NULL) {
74 e1 = s1;
75 for (i = skip_fields; i; i--) {
76 e1 = skip_whitespace(e1);
77 e1 = skip_non_whitespace(e1);
78 }
79 for (i = skip_chars; *e1 && i; i--) {
80 ++e1;
81 }
82
83 if (!s0 || strncmp(e0, e1, max_chars)) {
84 break;
85 }
86
87 ++dups; /* note: testing for overflow seems excessive. */
88 }
89
90 if (s0) {
91 if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_e) */
92 fprintf(out, "\0%ld " + (opt & 1), dups + 1); /* 1 == OPT_c */
93 fprintf(out, "%s\n", s0);
94 }
95 free((void *)s0);
96 }
97 } while (s1);
98
99 die_if_ferror(in, input_filename);
100
101 fflush_stdout_and_exit(EXIT_SUCCESS);
102 }