18e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda/* paste.c - Replace newlines 28e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda * 38e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda * Copyright 2012 Felix Janda <felix.janda@posteo.de> 48e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda * 58e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/paste.html 68e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda * 78e9ec867e5753e63778d67c3cb1cce68792f7b24Felix JandaUSE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_BIN)) 88e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 98e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Jandaconfig PASTE 108e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda bool "paste" 118e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda default y 128e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda help 138e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda usage: paste [-s] [-d list] [file...] 148e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 158e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda Replace newlines in files. 168e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 178e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda -d list list of delimiters to separate lines 188e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda -s process files sequentially instead of in parallel 198e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 208e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda By default print corresponding lines separated by <tab>. 218e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda*/ 228e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda#define FOR_paste 238e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda#include "toys.h" 248e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 258e9ec867e5753e63778d67c3cb1cce68792f7b24Felix JandaGLOBALS( 268e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda char *delim; 278e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda) 288e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 298e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Jandavoid paste_main(void) 308e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda{ 31c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham char *p, *buf = toybuf, **args = toys.optargs; 328e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda size_t ndelim = 0; 338e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda int i, j, c; 348e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 358e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda // Process delimiter list 368e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda // TODO: Handle multibyte characters 378e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (!(toys.optflags & FLAG_d)) TT.delim = "\t"; 38c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham for (p = TT.delim; *p; p++, buf++, ndelim++) { 398e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (*p == '\\') { 408e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda p++; 418e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (-1 == (i = stridx("nt\\0", *p))) 428e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda error_exit("bad delimiter: \\%c", *p); 438e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda *buf = "\n\t\\\0"[i]; 44c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham } else *buf = *p; 458e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 468e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda *buf = 0; 478e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda 488e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (toys.optflags & FLAG_s) { // Sequential 498e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda FILE *f; 50c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham 518e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda for (; *args; args++) { 528e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if ((*args)[0] == '-' && !(*args)[1]) f = stdin; 53d3a435e53c94ec25b4ae5fa2614f49ef8884e08aRob Landley else if (!(f = fopen(*args, "r"))) perror_exit_raw(*args); 548e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda for (i = 0, c = 0; c != EOF;) { 558e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda switch(c = getc(f)) { 568e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda case '\n': 578e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda putchar(toybuf[i++ % ndelim]); 588e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda case EOF: 598e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda break; 608e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda default: 618e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda putchar(c); 628e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 638e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 648e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (f != stdin) fclose(f); 658e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda putchar('\n'); 668e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 67c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham } else { // Parallel 688e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda // Need to be careful not to print an extra line at the end 698e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda FILE **files; 708e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda int anyopen = 1; 71c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham 728e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda files = (FILE**)(buf + 1); 738e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda for (; *args; args++, files++) { 748e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if ((*args)[0] == '-' && !(*args)[1]) *files = stdin; 75d3a435e53c94ec25b4ae5fa2614f49ef8884e08aRob Landley else if (!(*files = fopen(*args, "r"))) perror_exit_raw(*args); 768e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 77c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham while (anyopen) { 788e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda anyopen = 0; 798e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda for (i = 0; i < toys.optc; i++) { 808e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda FILE **f = (FILE**)(buf + 1) + i; 81c810f9f80b9db62de09b6cf4c6ca770eed72ce53Isaac Dunham 828e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (*f) for (;;) { 838e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda c = getc(*f); 848e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (c != EOF) { 858e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (!anyopen++) for (j = 0; j < i; j++) putchar(toybuf[j % ndelim]); 868e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (c != '\n') putchar(c); 878e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda else break; 888e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 898e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda else { 908e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (*f != stdin) fclose(*f); 918e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda *f = 0; 928e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda break; 938e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 948e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 958e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda if (anyopen) putchar((i + 1 == toys.optc) ? toybuf[i % ndelim] : '\n'); 968e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 978e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 988e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda } 998e9ec867e5753e63778d67c3cb1cce68792f7b24Felix Janda} 100