|
|
1.1 ! root 1: static char sccsid[] = "@(#)paste.c 1.1"; ! 2: # ! 3: /* paste: concatenate corresponding lines of each file in parallel. Release 1.4 (GWRL) */ ! 4: /* (-s option: serial concatenation like old (127's) paste command */ ! 5: # include <stdio.h> /* make : cc paste.c */ ! 6: # define MAXOPNF 12 /* maximal no. of open files (not with -s option) */ ! 7: # define MAXLINE 4096 /* maximal line length */ ! 8: #define RUB '\177' ! 9: char del[MAXLINE] = {"\t"}; ! 10: ! 11: main(argc, argv) ! 12: int argc; ! 13: char ** argv; ! 14: { ! 15: int i, j, k, eofcount, nfiles, maxline, glue; ! 16: int delcount = { 1 } ; ! 17: int onefile = { 0 } ; ! 18: register int c ; ! 19: char outbuf[MAXLINE], l, t; ! 20: register char *p; ! 21: FILE *inptr[MAXOPNF]; ! 22: ! 23: maxline = MAXLINE -2; ! 24: ! 25: while (argc > 1 && argv[1][0] == '-' && (c = argv[1][1]) != '\0'){ ! 26: switch (c) { ! 27: case 's' : onefile++; ! 28: c = argv[1][2]; ! 29: argv[1]++; ! 30: break ; ! 31: case 'd' : argv[1] += 2; ! 32: if((delcount = move(argv[1], &del[0])) == 0) ! 33: diag("no delimiters"); ! 34: break; ! 35: default : ! 36: fprintf(stderr,"Usage: paste [-s] [-d<delimiterstring>] file1 file2 ..."); ! 37: exit(1); ! 38: break; ! 39: } ! 40: --argc; ! 41: ++argv; ! 42: } /* end options */ ! 43: --argc; ! 44: ! 45: if ( ! onefile) { /* not -s option: parallel line merging */ ! 46: for (i = 0; argc >0 && i < MAXOPNF; i++) { ! 47: if (argv[i + 1][0] == '-') { ! 48: inptr[i] = stdin; ! 49: } else inptr[i] = fopen(argv[i + 1], "r"); ! 50: if (inptr[i] == NULL) ! 51: filerr(argv[i+1]); ! 52: argc--; ! 53: } ! 54: if (argc > 0) diag("too many files"); ! 55: nfiles = i; ! 56: ! 57: do { ! 58: p = &outbuf[0]; ! 59: eofcount = 0; ! 60: j = k = 0; ! 61: for (i = 0; i < nfiles; i++) { ! 62: while((c = getc(inptr[i])) != '\n' && c != EOF) { ! 63: if (++j <= maxline) *p++ = c ; ! 64: else { ! 65: diag("line too long"); ! 66: } ! 67: } ! 68: if ( (l = del[k]) != RUB) *p++ = l; ! 69: k = (k + 1) % delcount; ! 70: if( c == EOF) eofcount++; ! 71: } ! 72: if (l != RUB) *--p = '\n'; else *p = '\n'; ! 73: *++p = 0; ! 74: if (eofcount < nfiles) fputs(outbuf, stdout); ! 75: }while (eofcount < nfiles); ! 76: ! 77: } else { /* -s option: serial file pasting (old 127 paste command) */ ! 78: p = &outbuf[0]; ! 79: glue = 0; ! 80: j = 0; ! 81: k = 0; ! 82: t = 0; ! 83: for (i = 1; i <= argc; i++) { ! 84: if (argv[i][0] == '-') { ! 85: inptr[0] = stdin; ! 86: } else inptr[0] = fopen(argv[i], "r"); ! 87: if (inptr[0] == NULL) ! 88: filerr(argv[i]); ! 89: ! 90: while((c = getc(inptr[0])) != EOF) { ! 91: if (j >= maxline) { ! 92: t = *--p; ! 93: *++p = 0; ! 94: fputs(outbuf, stdout); ! 95: p = &outbuf[0]; ! 96: j = 0; ! 97: } ! 98: if (glue) { ! 99: glue = 0; ! 100: l = del[k]; ! 101: if (l != RUB) { ! 102: *p++ = l ; ! 103: t = l ; ! 104: j++; ! 105: } ! 106: k = (k + 1) % delcount; ! 107: } ! 108: if(c != '\n') { ! 109: *p++ = c; ! 110: t = c; ! 111: j++; ! 112: } else glue++; ! 113: } ! 114: if (t != '\n') { ! 115: *p++ = '\n'; ! 116: j++; ! 117: } ! 118: if (j > 0) { ! 119: *p = 0; ! 120: fputs(outbuf, stdout); ! 121: } ! 122: } ! 123: } ! 124: exit(0); ! 125: } ! 126: diag(s) ! 127: char *s; ! 128: { ! 129: fprintf(stderr, "paste: %s\n", s); ! 130: exit(1); ! 131: } ! 132: ! 133: filerr(s) ! 134: char *s; ! 135: { ! 136: fprintf(stderr, "paste: cannot open %s\n", s); ! 137: exit(1); ! 138: } ! 139: ! 140: move(from, to) ! 141: char *from, *to; ! 142: { ! 143: int c, i; ! 144: i = 0; ! 145: do { ! 146: c = *from++; ! 147: i++; ! 148: if (c != '\\') *to++ = c; ! 149: else { c = *from++; ! 150: switch (c) { ! 151: case '0' : *to++ = RUB; ! 152: break; ! 153: case 't' : *to++ = '\t'; ! 154: break; ! 155: case 'n' : *to++ = '\n'; ! 156: break; ! 157: default : *to++ = c; ! 158: break; ! 159: } ! 160: } ! 161: } while (c) ; ! 162: return(--i); ! 163: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.