|
|
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 512 /* 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) diag("no delimiters\n",1);;
33: break;
34: default :
35: diag("Usage: paste [-s] [-d<delimiterstring>] file1 file2 ...", 1);
36: break;
37: }
38: --argc;
39: ++argv;
40: } /* end options */
41: --argc;
42:
43: if ( ! onefile) { /* not -s option: parallel line merging */
44: for (i = 0; argc >0 && i < MAXOPNF; i++) {
45: if (argv[i + 1][0] == '-') {
46: inptr[i] = stdin;
47: } else inptr[i] = fopen(argv[i + 1], "r");
48: if (inptr[i] == NULL) {
49: diag(argv[i + 1], 0);
50: diag(" : cannot open\n", 1);
51: }
52: argc--;
53: }
54: if (argc > 0) diag("too many files\n",1);
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\n",1);
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: diag(argv[i], 0);
89: diag(" : cannot open\n", 1);
90: }
91:
92: while((c = getc(inptr[0])) != EOF) {
93: if (j >= maxline) {
94: t = *--p;
95: *++p = 0;
96: fputs(outbuf, stdout);
97: p = &outbuf[0];
98: j = 0;
99: }
100: if (glue) {
101: glue = 0;
102: l = del[k];
103: if (l != RUB) {
104: *p++ = l ;
105: t = l ;
106: j++;
107: }
108: k = (k + 1) % delcount;
109: }
110: if(c != '\n') {
111: *p++ = c;
112: t = c;
113: j++;
114: } else glue++;
115: }
116: if (t != '\n') {
117: *p++ = '\n';
118: j++;
119: }
120: if (j > 0) {
121: *p = 0;
122: fputs(outbuf, stdout);
123: }
124: }
125: }
126: }
127: diag(s,r)
128: char *s;
129: int r;
130: {
131: write(2, "paste : ", 8);
132: while(*s)write(2,s++,1);
133: if(r != 0) exit(r);
134: }
135:
136: move(from, to)
137: char *from, *to;
138: {
139: int c, i;
140: i = 0;
141: do {
142: c = *from++;
143: i++;
144: if (c != '\\') *to++ = c;
145: else { c = *from++;
146: switch (c) {
147: case '0' : *to++ = RUB;
148: break;
149: case 't' : *to++ = '\t';
150: break;
151: case 'n' : *to++ = '\n';
152: break;
153: default : *to++ = c;
154: break;
155: }
156: }
157: } while (c) ;
158: return(--i);
159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.