|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Adam S. Moskowitz of Menlo Consulting. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: static char sccsid[] = "@(#)paste.c 5.6 (Berkeley) 6/24/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <errno.h> ! 32: #include <limits.h> ! 33: #include <stdio.h> ! 34: #include <string.h> ! 35: ! 36: #if COHERENT ! 37: #define _BSD_LINE_MAX BUFSIZ /* compatibility */ ! 38: typedef unsigned int u_int; ! 39: char *index(); ! 40: #endif ! 41: ! 42: char *delim; ! 43: int delimcnt; ! 44: ! 45: main(argc, argv) ! 46: int argc; ! 47: char **argv; ! 48: { ! 49: extern char *optarg; ! 50: extern int optind; ! 51: int ch, seq; ! 52: ! 53: seq = 0; ! 54: while ((ch = getopt(argc, argv, "d:s")) != EOF) ! 55: switch(ch) { ! 56: case 'd': ! 57: delimcnt = tr(delim = optarg); ! 58: break; ! 59: case 's': ! 60: seq = 1; ! 61: break; ! 62: case '?': ! 63: default: ! 64: usage(); ! 65: } ! 66: argc -= optind; ! 67: argv += optind; ! 68: ! 69: if (!delim) { ! 70: delimcnt = 1; ! 71: delim = "\t"; ! 72: } ! 73: ! 74: if (seq) ! 75: sequential(argv); ! 76: else ! 77: parallel(argv); ! 78: exit(0); ! 79: } ! 80: ! 81: typedef struct _list { ! 82: struct _list *next; ! 83: FILE *fp; ! 84: int cnt; ! 85: char *name; ! 86: } LIST; ! 87: ! 88: parallel(argv) ! 89: char **argv; ! 90: { ! 91: register LIST *lp; ! 92: register int cnt; ! 93: register char ch, *p; ! 94: LIST *head, *tmp; ! 95: int opencnt, output; ! 96: char buf[_BSD_LINE_MAX + 1], *malloc(); ! 97: ! 98: for (cnt = 0, head = NULL; p = *argv; ++argv, ++cnt) { ! 99: if (!(lp = (LIST *)malloc((u_int)sizeof(LIST)))) { ! 100: (void)fprintf(stderr, "paste: %s.\n", strerror(ENOMEM)); ! 101: exit(1); ! 102: } ! 103: if (p[0] == '-' && !p[1]) ! 104: lp->fp = stdin; ! 105: else if (!(lp->fp = fopen(p, "r"))) { ! 106: (void)fprintf(stderr, "paste: %s: %s.\n", p, ! 107: strerror(errno)); ! 108: exit(1); ! 109: } ! 110: lp->next = NULL; ! 111: lp->cnt = cnt; ! 112: lp->name = p; ! 113: if (!head) ! 114: head = tmp = lp; ! 115: else { ! 116: tmp->next = lp; ! 117: tmp = lp; ! 118: } ! 119: } ! 120: ! 121: for (opencnt = cnt; opencnt;) { ! 122: for (output = 0, lp = head; lp; lp = lp->next) { ! 123: if (!lp->fp) { ! 124: if (output && lp->cnt && ! 125: (ch = delim[(lp->cnt - 1) % delimcnt])) ! 126: putchar(ch); ! 127: continue; ! 128: } ! 129: if (!fgets(buf, sizeof(buf), lp->fp)) { ! 130: if (!--opencnt) ! 131: break; ! 132: lp->fp = NULL; ! 133: if (output && lp->cnt && ! 134: (ch = delim[(lp->cnt - 1) % delimcnt])) ! 135: putchar(ch); ! 136: continue; ! 137: } ! 138: if (!(p = index(buf, '\n'))) { ! 139: (void)fprintf(stderr, ! 140: "paste: %s: input line too long.\n", ! 141: lp->name); ! 142: exit(1); ! 143: } ! 144: *p = '\0'; ! 145: /* ! 146: * make sure that we don't print any delimiters ! 147: * unless there's a non-empty file. ! 148: */ ! 149: if (!output) { ! 150: output = 1; ! 151: for (cnt = 0; cnt < lp->cnt; ++cnt) ! 152: if (ch = delim[cnt % delimcnt]) ! 153: putchar(ch); ! 154: } else if (ch = delim[(lp->cnt - 1) % delimcnt]) ! 155: putchar(ch); ! 156: (void)printf("%s", buf); ! 157: } ! 158: if (output) ! 159: putchar('\n'); ! 160: } ! 161: } ! 162: ! 163: sequential(argv) ! 164: char **argv; ! 165: { ! 166: register FILE *fp; ! 167: register int cnt; ! 168: register char ch, *p, *dp; ! 169: char buf[_BSD_LINE_MAX + 1]; ! 170: ! 171: for (; p = *argv; ++argv) { ! 172: if (p[0] == '-' && !p[1]) ! 173: fp = stdin; ! 174: else if (!(fp = fopen(p, "r"))) { ! 175: (void)fprintf(stderr, "paste: %s: %s.\n", p, ! 176: strerror(errno)); ! 177: continue; ! 178: } ! 179: if (fgets(buf, sizeof(buf), fp)) { ! 180: for (cnt = 0, dp = delim;;) { ! 181: if (!(p = index(buf, '\n'))) { ! 182: (void)fprintf(stderr, ! 183: "paste: %s: input line too long.\n", ! 184: *argv); ! 185: exit(1); ! 186: } ! 187: *p = '\0'; ! 188: (void)printf("%s", buf); ! 189: if (!fgets(buf, sizeof(buf), fp)) ! 190: break; ! 191: if (ch = *dp++) ! 192: putchar(ch); ! 193: if (++cnt == delimcnt) { ! 194: dp = delim; ! 195: cnt = 0; ! 196: } ! 197: } ! 198: putchar('\n'); ! 199: } ! 200: if (fp != stdin) ! 201: (void)fclose(fp); ! 202: } ! 203: } ! 204: ! 205: tr(arg) ! 206: char *arg; ! 207: { ! 208: register int cnt; ! 209: register char ch, *p; ! 210: ! 211: for (p = arg, cnt = 0; (ch = *p++); ++arg, ++cnt) ! 212: if (ch == '\\') ! 213: switch(ch = *p++) { ! 214: case 'n': ! 215: *arg = '\n'; ! 216: break; ! 217: case 't': ! 218: *arg = '\t'; ! 219: break; ! 220: case '0': ! 221: *arg = '\0'; ! 222: break; ! 223: default: ! 224: *arg = ch; ! 225: break; ! 226: } else ! 227: *arg = ch; ! 228: ! 229: if (!cnt) { ! 230: (void)fprintf(stderr, "paste: no delimiters specified.\n"); ! 231: exit(1); ! 232: } ! 233: return(cnt); ! 234: } ! 235: ! 236: usage() ! 237: { ! 238: (void)fprintf(stderr, "paste: [-s] [-d delimiters] file ...\n"); ! 239: exit(1); ! 240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.