1 /* paste.c - Replace newlines
3 * Copyright 2012 Felix Janda <felix.janda@posteo.de>
5 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/paste.html
7 USE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_BIN))
13 usage: paste [-s] [-d list] [file...]
15 Replace newlines in files.
17 -d list list of delimiters to separate lines
18 -s process files sequentially instead of in parallel
20 By default print corresponding lines separated by <tab>.
31 char *p, *buf = toybuf, **args = toys.optargs;
35 // Process delimiter list
36 // TODO: Handle multibyte characters
37 if (!(toys.optflags & FLAG_d)) TT.delim = "\t";
38 for (p = TT.delim; *p; p++, buf++, ndelim++) {
41 if (-1 == (i = stridx("nt\\0", *p)))
42 error_exit("bad delimiter: \\%c", *p);
48 if (toys.optflags & FLAG_s) { // Sequential
51 for (; *args; args++) {
52 if ((*args)[0] == '-' && !(*args)[1]) f = stdin;
53 else if (!(f = fopen(*args, "r"))) perror_exit_raw(*args);
54 for (i = 0, c = 0; c != EOF;) {
57 putchar(toybuf[i++ % ndelim]);
64 if (f != stdin) fclose(f);
68 // Need to be careful not to print an extra line at the end
72 files = (FILE**)(buf + 1);
73 for (; *args; args++, files++) {
74 if ((*args)[0] == '-' && !(*args)[1]) *files = stdin;
75 else if (!(*files = fopen(*args, "r"))) perror_exit_raw(*args);
79 for (i = 0; i < toys.optc; i++) {
80 FILE **f = (FILE**)(buf + 1) + i;
85 if (!anyopen++) for (j = 0; j < i; j++) putchar(toybuf[j % ndelim]);
86 if (c != '\n') putchar(c);
90 if (*f != stdin) fclose(*f);
95 if (anyopen) putchar((i + 1 == toys.optc) ? toybuf[i % ndelim] : '\n');