/* See LICENSE file for copyright and license details. */ #include <stdlib.h> #include <string.h> #include "utf.h" #include "util.h" struct fdescr { FILE *fp; const char *name; }; static void sequential(struct fdescr *dsc, int fdescrlen, Rune *delim, size_t delimlen) { Rune c, last; size_t i, d; for (i = 0; i < fdescrlen; i++) { d = 0; last = 0; while (efgetrune(&c, dsc[i].fp, dsc[i].name)) { if (last == '\n') { if (delim[d] != '\0') efputrune(&delim[d], stdout, "<stdout>"); d = (d + 1) % delimlen; } if (c != '\n') efputrune(&c, stdout, "<stdout>"); last = c; } if (last == '\n') efputrune(&last, stdout, "<stdout>"); } } static void parallel(struct fdescr *dsc, int fdescrlen, Rune *delim, size_t delimlen) { Rune c, d; size_t i, m; ssize_t last; nextline: last = -1; for (i = 0; i < fdescrlen; i++) { d = delim[i % delimlen]; c = 0; for (; efgetrune(&c, dsc[i].fp, dsc[i].name) ;) { for (m = last + 1; m < i; m++) efputrune(&(delim[m % delimlen]), stdout, "<stdout>"); last = i; if (c == '\n') { if (i != fdescrlen - 1) c = d; efputrune(&c, stdout, "<stdout>"); break; } efputrune(&c, stdout, "<stdout>"); } if (c == 0 && last != -1) { if (i == fdescrlen - 1) putchar('\n'); else efputrune(&d, stdout, "<stdout>"); last++; } } if (last != -1) goto nextline; } static void usage(void) { eprintf("usage: %s [-s] [-d list] file ...\n", argv0); } int main(int argc, char *argv[]) { struct fdescr *dsc; Rune *delim; size_t i, len; int seq = 0; char *adelim = "\t"; ARGBEGIN { case 's': seq = 1; break; case 'd': adelim = EARGF(usage()); break; default: usage(); } ARGEND; if (argc == 0) usage(); /* populate delimiters */ unescape(adelim); delim = emalloc((utflen(adelim) + 1) * sizeof(*delim)); len = utftorunestr(adelim, delim); /* populate file list */ dsc = emalloc(argc * sizeof(*dsc)); for (i = 0; i < argc; i++) { if (strcmp(argv[i], "-") == 0) dsc[i].fp = stdin; else dsc[i].fp = fopen(argv[i], "r"); if (!dsc[i].fp) eprintf("fopen %s:", argv[i]); dsc[i].name = argv[i]; } if (seq) sequential(dsc, argc, delim, len); else parallel(dsc, argc, delim, len); for (i = 0; i < argc; i++) fclose(dsc[i].fp); return 0; }