/* uniq.c - report or filter out repeated lines in a file
 *
 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/uniq.html

USE_UNIQ(NEWTOY(uniq, "f#s#w#zicdu", TOYFLAG_USR|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
*/

#define FOR_uniq
#include "toys.h"

GLOBALS(
  long w, s, f;

  long repeats;
)

static char *skip(char *str)
{
  long nchars = TT.s, nfields = TT.f;

  // Skip fields first
  while (nfields--) {
    while (*str && isspace(*str)) str++;
    while (*str && !isspace(*str)) str++;
  }
  // Skip chars
  while (*str && nchars--) str++;

  return str;
}

static void print_line(FILE *f, char *line)
{
  if (TT.repeats ? FLAG(u) : FLAG(d)) return;
  if (FLAG(c)) fprintf(f, "%7lu ", TT.repeats + 1);
  fputs(line, f);
  if (FLAG(z)) fputc(0, f);
}

void uniq_main(void)
{
  FILE *infile = stdin, *outfile = stdout;
  char *thisline = 0, *prevline = 0, *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 (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.f || TT.s) {
      t1 = skip(thisline);
      t2 = skip(prevline);
    } else {
      t1 = thisline;
      t2 = prevline;
    }

    if (!TT.w)
      diff = !FLAG(i) ? strcmp(t1, t2) : strcasecmp(t1, t2);
    else diff = !FLAG(i) ? strncmp(t1, t2, TT.w) : strncasecmp(t1, t2, TT.w);

    if (!diff) 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) {
    if (outfile != stdout) fclose(outfile);
    if (infile != stdin) fclose(infile);
    free(prevline);
    free(thisline);
  }
}
