source: MondoRescue/branches/stable/mindi-busybox/coreutils/uniq.c @ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 14 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.