/* 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;
      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 = 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();
}
