/* wc.c - Word count
 *
 * Copyright 2011 Rob Landley <rob@landley.net>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/wc.html

USE_WC(NEWTOY(wc, "mcwl", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))

config WC
  bool "wc"
  default y
  help
    usage: wc -lwcm [FILE...]

    Count lines, words, and characters in input.

    -l	show lines
    -w	show words
    -c	show bytes
    -m	show characters

    By default outputs lines, words, bytes, and filename for each
    argument (or from stdin if none). Displays only either bytes
    or characters.
*/

#define FOR_wc
#include "toys.h"

GLOBALS(
  unsigned long totals[4];
)

static void show_lengths(unsigned long *lengths, char *name)
{
  int i, space = 7, first = 1;

  for (i = 0; i<4; i++) if (toys.optflags == (1<<i)) space = 0;
  for (i = 0; i<4; i++) {
    if (toys.optflags&(1<<i)) {
      printf(" %*ld"+first, space, lengths[i]);
      first = 0;
    }
    TT.totals[i] += lengths[i];
  }
  if (*toys.optargs) printf(" %s", name);
  xputc('\n');
}

static void do_wc(int fd, char *name)
{
  int len = 0, clen = 1, space = 0;
  unsigned long word = 0, lengths[] = {0,0,0,0};

  // Speed up common case: wc -c normalfile is file length.
  if (toys.optflags == FLAG_c) {
    struct stat st;

    // On Linux, files in /proc often report their size as 0.
    if (!fstat(fd, &st) && S_ISREG(st.st_mode) && st.st_size) {
      lengths[2] = st.st_size;
      goto show;
    }
  }

  for (;;) {
    int pos, done = 0, len2 = read(fd, toybuf+len, sizeof(toybuf)-len);

    if (len2<0) perror_msg_raw(name);
    else len += len2;
    if (len2<1) done++;

    for (pos = 0; pos<len; pos++) {
      if (toybuf[pos]=='\n') lengths[0]++;
      lengths[2]++;
      if (toys.optflags&FLAG_m) {
        // If we've consumed next wide char
        if (--clen<1) {
          wchar_t wchar;

          // next wide size, don't count invalid, fetch more data if necessary
          clen = mbrtowc(&wchar, toybuf+pos, len-pos, 0);
          if (clen == -1) continue;
          if (clen == -2 && !done) break;

          lengths[3]++;
          space = iswspace(wchar);
        }
      } else space = isspace(toybuf[pos]);

      if (space) word=0;
      else {
        if (!word) lengths[1]++;
        word=1;
      }
    }
    if (done) break;
    if (pos != len) memmove(toybuf, toybuf+pos, len-pos);
    len -= pos;
  }

show:
  show_lengths(lengths, name);
}

void wc_main(void)
{
  if (!toys.optflags) toys.optflags = FLAG_l|FLAG_w|FLAG_c;
  loopfiles(toys.optargs, do_wc);
  if (toys.optc>1) show_lengths(TT.totals, "total");
}
