|
|
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.