diff options
Diffstat (limited to 'toys/posix/uniq.c')
-rw-r--r-- | toys/posix/uniq.c | 189 |
1 files changed, 92 insertions, 97 deletions
diff --git a/toys/posix/uniq.c b/toys/posix/uniq.c index f42b7293..bd41d4af 100644 --- a/toys/posix/uniq.c +++ b/toys/posix/uniq.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * uniq.c - report or filter out repeated lines in a file +/* uniq.c - report or filter out repeated lines in a file * * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org> * @@ -9,116 +7,113 @@ USE_UNIQ(NEWTOY(uniq, "f#s#w#zicdu", TOYFLAG_BIN)) config UNIQ - bool "uniq" - default y - help - usage: uniq [-cduiz] [-w maxchars] [-f fields] [-s char] [input_file [output_file]] - - Report or filter out repeated lines in a file - - -c show counts before each line - -d show only lines that are repeated - -u show only lines that are unique - -i ignore case when comparing lines - -z lines end with \0 not \n - -w compare maximum X chars per line - -f ignore first X fields - -s ignore first X chars + bool "uniq" + default y + help + usage: uniq [-cduiz] [-w maxchars] [-f fields] [-s char] [input_file [output_file]] + + Report or filter out repeated lines in a file + + -c show counts before each line + -d show only lines that are repeated + -u show only lines that are unique + -i ignore case when comparing lines + -z lines end with \0 not \n + -w compare maximum X chars per line + -f ignore first X fields + -s ignore first X chars */ #define FOR_uniq #include "toys.h" GLOBALS( - long maxchars; - long nchars; - long nfields; - long repeats; + long maxchars; + long nchars; + long nfields; + long repeats; ) static char *skip(char *str) { - long nchars = TT.nchars, nfields; - - // Skip fields first - for (nfields = TT.nfields; nfields; str++) { - while (*str && isspace(*str)) str++; - while (*str && !isspace(*str)) str++; - nfields--; - } - // Skip chars - while (*str && nchars--) str++; - - return str; + long nchars = TT.nchars, nfields; + + // Skip fields first + for (nfields = TT.nfields; nfields; str++) { + while (*str && isspace(*str)) str++; + while (*str && !isspace(*str)) str++; + nfields--; + } + // Skip chars + while (*str && nchars--) str++; + + return str; } static void print_line(FILE *f, char *line) { - if (toys.optflags & (TT.repeats ? FLAG_u : FLAG_d)) return; - if (toys.optflags & FLAG_c) fprintf(f, "%7lu ", TT.repeats + 1); - fputs(line, f); - if (toys.optflags & FLAG_z) fputc(0, f); + if (toys.optflags & (TT.repeats ? FLAG_u : FLAG_d)) return; + if (toys.optflags & FLAG_c) fprintf(f, "%7lu ", TT.repeats + 1); + fputs(line, f); + if (toys.optflags & FLAG_z) fputc(0, f); } void uniq_main(void) { - FILE *infile = stdin, *outfile = stdout; - char *thisline = NULL, *prevline = NULL, *tmpline, eol = '\n'; - size_t thissize, prevsize = 0, tmpsize; - - if (toys.optc >= 1) infile = xfopen(toys.optargs[0], "r"); - if (toys.optc >= 2) outfile = xfopen(toys.optargs[1], "w"); - - if (toys.optflags & FLAG_z) eol = 0; - - // If first line can't be read - if (getdelim(&prevline, &prevsize, eol, infile) < 0) - return; - - while (getdelim(&thisline, &thissize, eol, infile) > 0) { - int diff; - char *t1, *t2; - - // If requested get the chosen fields + character offsets. - if (TT.nfields || TT.nchars) { - t1 = skip(thisline); - t2 = skip(prevline); - } else { - t1 = thisline; - t2 = prevline; - } - - if (TT.maxchars == 0) { - diff = !(toys.optflags & FLAG_i) - ? strcmp(t1, t2) - : strcasecmp(t1, t2); - } else { - diff = !(toys.optflags & FLAG_i) - ? strncmp(t1, t2, TT.maxchars) - : strncasecmp(t1, t2, TT.maxchars); - } - - if (diff == 0) { // same - TT.repeats++; - } else { - print_line(outfile, prevline); - - TT.repeats = 0; - - tmpline = prevline; - prevline = thisline; - thisline = tmpline; - - tmpsize = prevsize; - prevsize = thissize; - thissize = tmpsize; - } - } - - print_line(outfile, prevline); - - if (CFG_TOYBOX_FREE) { - free(prevline); - free(thisline); - } + FILE *infile = stdin, *outfile = stdout; + char *thisline = NULL, *prevline = NULL, *tmpline, eol = '\n'; + size_t thissize, prevsize = 0, tmpsize; + + if (toys.optc >= 1) infile = xfopen(toys.optargs[0], "r"); + if (toys.optc >= 2) outfile = xfopen(toys.optargs[1], "w"); + + if (toys.optflags & FLAG_z) eol = 0; + + // If first line can't be read + if (getdelim(&prevline, &prevsize, eol, infile) < 0) + return; + + while (getdelim(&thisline, &thissize, eol, infile) > 0) { + int diff; + char *t1, *t2; + + // If requested get the chosen fields + character offsets. + if (TT.nfields || TT.nchars) { + t1 = skip(thisline); + t2 = skip(prevline); + } else { + t1 = thisline; + t2 = prevline; + } + + if (TT.maxchars == 0) { + diff = !(toys.optflags & FLAG_i) ? strcmp(t1, t2) : strcasecmp(t1, t2); + } else { + diff = !(toys.optflags & FLAG_i) ? strncmp(t1, t2, TT.maxchars) + : strncasecmp(t1, t2, TT.maxchars); + } + + if (diff == 0) { // same + TT.repeats++; + } else { + print_line(outfile, prevline); + + TT.repeats = 0; + + tmpline = prevline; + prevline = thisline; + thisline = tmpline; + + tmpsize = prevsize; + prevsize = thissize; + thissize = tmpsize; + } + } + + print_line(outfile, prevline); + + if (CFG_TOYBOX_FREE) { + free(prevline); + free(thisline); + } } |