/* paste.c - Merge corresponding lines
 *
 * Copyright 2012 Felix Janda <felix.janda@posteo.de>
 *
 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/paste.html 
 *
 * Deviations from posix: the FILE argument isn't mandatory, none == '-'

USE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_BIN|TOYFLAG_LOCALE))

config PASTE
  bool "paste"
  default y
  help
    usage: paste [-s] [-d DELIMITERS] [FILE...]

    Merge corresponding lines from each input file.

    -d	list of delimiter characters to separate fields with (default is \t)
    -s	sequential mode: turn each input file into one line of output
*/

#define FOR_paste
#include "toys.h"

GLOBALS(
  char *d;

  int files;
)

// \0 is weird, and -d "" is also weird.

static void paste_files(void)
{
  FILE **fps = (void *)toybuf;
  char *dpos, *dstr, *buf, c;
  int i, any, dcount, dlen, len, seq = toys.optflags&FLAG_s;

  // Loop through lines until no input left
  for (;;) {

    // Start of each line/file resets delimiter cycle
    dpos = TT.d;
    mbtowc(0, 0, 0);

    for (i = any = dcount = dlen = 0; seq || i<TT.files; i++) {
      size_t blen;
      wchar_t wc;
      FILE *ff = seq ? *fps : fps[i];

      // Read and output line, preserving embedded NUL bytes.

      buf = 0;
      len = 0;
      if (!ff || 0>=(len = getline(&buf, &blen, ff))) {
        if (ff && ff!=stdin) fclose(ff);
        if (seq) return;
        fps[i] = 0;
        if (!any) continue;
      }
      dcount = any ? 1 : i;
      any = 1;

      // Output delimiters as necessary: not at beginning/end of line,
      // catch up if first few files had no input but a later one did.
      // Entire line with no input means no output.

      while (dcount) {

        // Find next delimiter, which can be "", \n, or UTF8 w/combining chars
        dstr = dpos;
        dlen = 0;
        dcount--;

        if (!*TT.d) {;}
        else if (*dpos == '\\') {
          if (*++dpos=='0') dpos++;
          else {
            dlen = 1;
            if ((c = unescape(*dpos))) {
              dstr = &c;
              dpos++;
            }
          }
        } else {
          while (0<(dlen = mbtowc(&wc, dpos, 99))) {
            dpos += dlen;
            if (!(dlen = wcwidth(wc))) continue;
            if (dlen<0) dpos = dstr+1;
            break;
          }
          dlen = dpos-dstr;
        }
        if (!*dpos) dpos = TT.d;

        if (dlen) fwrite(dstr, dlen, 1, stdout);
      }

      if (0<len) {
        fwrite(buf, len-(buf[len-1]=='\n'), 1, stdout);
        free(buf);
      }
    }

    // Only need a newline if we output something
    if (any) xputc('\n');
    else break;
  }
}

static void do_paste(int fd, char *name)
{
  FILE **fps = (void *)toybuf;

  if (!(fps[TT.files++] = (fd ? fdopen(fd, "r") : stdin))) perror_exit(0);
  if (TT.files >= sizeof(toybuf)/sizeof(FILE *)) perror_exit("tilt");
  if (toys.optflags&FLAG_s) {
    paste_files();
    xputc('\n');
    TT.files = 0;
  }
}

void paste_main(void)
{
  if (!(toys.optflags&FLAG_d)) TT.d = "\t";

  loopfiles_rw(toys.optargs, O_RDONLY, 0, do_paste);
  if (!(toys.optflags&FLAG_s)) paste_files();
}
