source: MondoRescue/trunk/mindi-busybox/coreutils/uniq.c@ 929

Last change on this file since 929 was 821, checked in by Bruno Cornec, 18 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 2.1 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 "busybox.h"
14#include <string.h>
15#include <ctype.h>
16#include <unistd.h>
17
18static const char uniq_opts[] = "f:s:" "cdu\0\1\2\4";
19
20static FILE *xgetoptfile_uniq_s(char **argv, int read0write2)
21{
22 const char *n;
23
24 if ((n = *argv) != NULL) {
25 if ((*n != '-') || n[1]) {
26 return bb_xfopen(n, "r\0w" + read0write2);
27 }
28 }
29 return (read0write2) ? stdout : stdin;
30}
31
32int uniq_main(int argc, char **argv)
33{
34 FILE *in, *out;
35 unsigned long dups, skip_fields, skip_chars, i, uniq_flags;
36 const char *s0, *e0, *s1, *e1, *input_filename;
37 int opt;
38
39 uniq_flags = skip_fields = skip_chars = 0;
40
41 while ((opt = getopt(argc, argv, uniq_opts)) > 0) {
42 if ((opt == 'f') || (opt == 's')) {
43 int t = bb_xgetularg10(optarg);
44 if (opt == 'f') {
45 skip_fields = t;
46 } else {
47 skip_chars = t;
48 }
49 } else if ((s0 = strchr(uniq_opts, opt)) != NULL) {
50 uniq_flags |= s0[4];
51 } else {
52 bb_show_usage();
53 }
54 }
55
56 input_filename = *(argv += optind);
57
58 in = xgetoptfile_uniq_s(argv, 0);
59 if (*argv) {
60 ++argv;
61 }
62 out = xgetoptfile_uniq_s(argv, 2);
63 if (*argv && argv[1]) {
64 bb_show_usage();
65 }
66
67 s1 = e1 = NULL; /* prime the pump */
68
69 do {
70 s0 = s1;
71 e0 = e1;
72 dups = 0;
73
74 /* gnu uniq ignores newlines */
75 while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) {
76 e1 = s1;
77 for (i=skip_fields ; i ; i--) {
78 e1 = skip_whitespace(e1);
79 while (*e1 && !isspace(*e1)) {
80 ++e1;
81 }
82 }
83 for (i = skip_chars ; *e1 && i ; i--) {
84 ++e1;
85 }
86
87 if (!s0 || strcmp(e0, e1)) {
88 break;
89 }
90
91 ++dups; /* Note: Testing for overflow seems excessive. */
92 }
93
94 if (s0) {
95 if (!(uniq_flags & (2 << !!dups))) {
96 bb_fprintf(out, "\0%d " + (uniq_flags & 1), dups + 1);
97 bb_fprintf(out, "%s\n", s0);
98 }
99 free((void *)s0);
100 }
101 } while (s1);
102
103 bb_xferror(in, input_filename);
104
105 bb_fflush_stdout_and_exit(EXIT_SUCCESS);
106}
Note: See TracBrowser for help on using the repository browser.