|
|
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: #endif /* not lint */ ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)paste.c 5.6 (Berkeley) 6/24/90"; ! 31: #endif /* not lint */ ! 32: ! 33: #include <sys/types.h> ! 34: #include <errno.h> ! 35: #include <limits.h> ! 36: #include <stdio.h> ! 37: #include <string.h> ! 38: ! 39: char *delim; ! 40: int delimcnt; ! 41: ! 42: main(argc, argv) ! 43: int argc; ! 44: char **argv; ! 45: { ! 46: extern char *optarg; ! 47: extern int optind; ! 48: int ch, seq; ! 49: ! 50: seq = 0; ! 51: while ((ch = getopt(argc, argv, "d:s")) != EOF) ! 52: switch(ch) { ! 53: case 'd': ! 54: delimcnt = tr(delim = optarg); ! 55: break; ! 56: case 's': ! 57: seq = 1; ! 58: break; ! 59: case '?': ! 60: default: ! 61: usage(); ! 62: } ! 63: argc -= optind; ! 64: argv += optind; ! 65: ! 66: if (!delim) { ! 67: delimcnt = 1; ! 68: delim = "\t"; ! 69: } ! 70: ! 71: if (seq) ! 72: sequential(argv); ! 73: else ! 74: parallel(argv); ! 75: exit(0); ! 76: } ! 77: ! 78: typedef struct _list { ! 79: struct _list *next; ! 80: FILE *fp; ! 81: int cnt; ! 82: char *name; ! 83: } LIST; ! 84: ! 85: parallel(argv) ! 86: char **argv; ! 87: { ! 88: register LIST *lp; ! 89: register int cnt; ! 90: register char ch, *p; ! 91: LIST *head, *tmp; ! 92: int opencnt, output; ! 93: char buf[_BSD_LINE_MAX + 1], *malloc(); ! 94: ! 95: for (cnt = 0, head = NULL; p = *argv; ++argv, ++cnt) { ! 96: if (!(lp = (LIST *)malloc((u_int)sizeof(LIST)))) { ! 97: (void)fprintf(stderr, "paste: %s.\n", strerror(ENOMEM)); ! 98: exit(1); ! 99: } ! 100: if (p[0] == '-' && !p[1]) ! 101: lp->fp = stdin; ! 102: else if (!(lp->fp = fopen(p, "r"))) { ! 103: (void)fprintf(stderr, "paste: %s: %s.\n", p, ! 104: strerror(errno)); ! 105: exit(1); ! 106: } ! 107: lp->next = NULL; ! 108: lp->cnt = cnt; ! 109: lp->name = p; ! 110: if (!head) ! 111: head = tmp = lp; ! 112: else { ! 113: tmp->next = lp; ! 114: tmp = lp; ! 115: } ! 116: } ! 117: ! 118: for (opencnt = cnt; opencnt;) { ! 119: for (output = 0, lp = head; lp; lp = lp->next) { ! 120: if (!lp->fp) { ! 121: if (output && lp->cnt && ! 122: (ch = delim[(lp->cnt - 1) % delimcnt])) ! 123: putchar(ch); ! 124: continue; ! 125: } ! 126: if (!fgets(buf, sizeof(buf), lp->fp)) { ! 127: if (!--opencnt) ! 128: break; ! 129: lp->fp = NULL; ! 130: if (output && lp->cnt && ! 131: (ch = delim[(lp->cnt - 1) % delimcnt])) ! 132: putchar(ch); ! 133: continue; ! 134: } ! 135: if (!(p = index(buf, '\n'))) { ! 136: (void)fprintf(stderr, ! 137: "paste: %s: input line too long.\n", ! 138: lp->name); ! 139: exit(1); ! 140: } ! 141: *p = '\0'; ! 142: /* ! 143: * make sure that we don't print any delimiters ! 144: * unless there's a non-empty file. ! 145: */ ! 146: if (!output) { ! 147: output = 1; ! 148: for (cnt = 0; cnt < lp->cnt; ++cnt) ! 149: if (ch = delim[cnt % delimcnt]) ! 150: putchar(ch); ! 151: } else if (ch = delim[(lp->cnt - 1) % delimcnt]) ! 152: putchar(ch); ! 153: (void)printf("%s", buf); ! 154: } ! 155: if (output) ! 156: putchar('\n'); ! 157: } ! 158: } ! 159: ! 160: sequential(argv) ! 161: char **argv; ! 162: { ! 163: register FILE *fp; ! 164: register int cnt; ! 165: register char ch, *p, *dp; ! 166: char buf[_BSD_LINE_MAX + 1]; ! 167: ! 168: for (; p = *argv; ++argv) { ! 169: if (p[0] == '-' && !p[1]) ! 170: fp = stdin; ! 171: else if (!(fp = fopen(p, "r"))) { ! 172: (void)fprintf(stderr, "paste: %s: %s.\n", p, ! 173: strerror(errno)); ! 174: continue; ! 175: } ! 176: if (fgets(buf, sizeof(buf), fp)) { ! 177: for (cnt = 0, dp = delim;;) { ! 178: if (!(p = index(buf, '\n'))) { ! 179: (void)fprintf(stderr, ! 180: "paste: %s: input line too long.\n", ! 181: *argv); ! 182: exit(1); ! 183: } ! 184: *p = '\0'; ! 185: (void)printf("%s", buf); ! 186: if (!fgets(buf, sizeof(buf), fp)) ! 187: break; ! 188: if (ch = *dp++) ! 189: putchar(ch); ! 190: if (++cnt == delimcnt) { ! 191: dp = delim; ! 192: cnt = 0; ! 193: } ! 194: } ! 195: putchar('\n'); ! 196: } ! 197: if (fp != stdin) ! 198: (void)fclose(fp); ! 199: } ! 200: } ! 201: ! 202: tr(arg) ! 203: char *arg; ! 204: { ! 205: register int cnt; ! 206: register char ch, *p; ! 207: ! 208: for (p = arg, cnt = 0; (ch = *p++); ++arg, ++cnt) ! 209: if (ch == '\\') ! 210: switch(ch = *p++) { ! 211: case 'n': ! 212: *arg = '\n'; ! 213: break; ! 214: case 't': ! 215: *arg = '\t'; ! 216: break; ! 217: case '0': ! 218: *arg = '\0'; ! 219: break; ! 220: default: ! 221: *arg = ch; ! 222: break; ! 223: } else ! 224: *arg = ch; ! 225: ! 226: if (!cnt) { ! 227: (void)fprintf(stderr, "paste: no delimiters specified.\n"); ! 228: exit(1); ! 229: } ! 230: return(cnt); ! 231: } ! 232: ! 233: usage() ! 234: { ! 235: (void)fprintf(stderr, "paste: [-s] [-d delimiters] file ...\n"); ! 236: exit(1); ! 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.