/* 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_USR|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;

    for (i = any = dcount = dlen = 0; seq || i<TT.files; i++) {
      size_t blen;
      unsigned 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 = utf8towc(&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();
}
