Bell 32V release
[unix-history] / usr / src / cmd / paste.c
CommitLineData
3b600ead
TL
1#
2/* paste: concatenate corresponding lines of each file in parallel(GWRL) */
3/* (-s option: serial concatenation like old (127's) paste command */
4/* make : cc paste.c -lS */
5# include <stdio.h>
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
11main(argc, argv)
12int argc;
13char ** argv;
14{
15 int i, j, k, eofcount, nfiles;
16 int delcount = { 1 } ;
17 int onefile = { 0 } ;
18 char outbuf[MAXLINE], c, l ;
19 register char *p;
20 FILE *inptr[MAXOPNF];
21
22 while (argc > 1 && argv[1][0] == '-' && (c = argv[1][1]) != '\0'){
23 switch (c) {
24 case 's' : onefile++;
25 c = argv[1][2];
26 argv[1]++;
27 break ;
28 case 'd' : argv[1] += 2;
29 if((delcount = move(argv[1], &del[0])) == 0) diag("no delimiters\n",1);;
30 break;
31 default :
32 diag("Usage: paste [-s] [-d<delimiterstring>] file1 file2 ...", 1);
33 break;
34 }
35 --argc;
36 ++argv;
37 } /* end options */
38 --argc;
39
40 if ( ! onefile) { /* not -s option: parallel line merging */
41 for (i = 0; argc >0 && i < MAXOPNF; i++) {
42 if (argv[i + 1][0] == '-') {
43 inptr[i] = stdin;
44 } else inptr[i] = fopen(argv[i + 1], "r");
45 if (inptr[i] == NULL) {
46 diag(argv[i + 1], 0);
47 diag(" : cannot open\n", 1);
48 }
49 argc--;
50 }
51 if (argc > 0) diag("too many files\n",1);
52 nfiles = i;
53
54 do {
55 p = &outbuf[0];
56 eofcount = 0;
57 j = k = 0;
58 for (i = 0; i < nfiles; i++) {
59 while((c = getc(inptr[i])) != '\n' && c != EOF) {
60 if (++j <= MAXLINE - 2) *p++ = c ;
61 else {
62 diag("line too long\n",1);
63 }
64 }
65 if ( (l = del[k]) != RUB) *p++ = l;
66 k = (k + 1) % delcount;
67 if( c == EOF) eofcount++;
68 }
69 if (l != RUB) *--p = '\n'; else *p = '\n';
70 *++p = 0;
71 if (eofcount < nfiles) fputs(outbuf, stdout);
72 }while (eofcount < nfiles);
73
74 } else { /* -s option: serial file pasting (old 127 paste command) */
75 p = &outbuf[0];
76 j = 0;
77 k = 0;
78 for (i = 1; i <= argc; i++) {
79 if (argv[i][0] == '-') {
80 inptr[0] = stdin;
81 } else inptr[0] = fopen(argv[i], "r");
82 if (inptr[0] == NULL) {
83 diag(argv[i], 0);
84 diag(" : cannot open\n", 1);
85 }
86
87 while((c = getc(inptr[0])) != EOF) {
88 if(c != '\n') {
89 if (++j <= MAXLINE - 2) *p++ = c ;
90 else diag("line too long\n",1);
91 } else {
92 l = del[k];
93 if (l != RUB) *p++ = l ;
94 k = (k + 1) % delcount;
95 *p = 0;
96 fputs(outbuf, stdout);
97 p = &outbuf[0];
98 j = 0;
99 }
100 }
101 }
102 if (l != '\n') fputs("\n", stdout);
103 }
104}
105diag(s,r)
106char *s;
107int r;
108{
109 write(2, "paste : ", 8);
110 while(*s)write(2,s++,1);
111 if(r != 0) exit(r);
112}
113
114move(from, to)
115char *from, *to;
116{
117int c, i;
118 i = 0;
119 do {
120 c = *from++;
121 i++;
122 if (c != '\\') *to++ = c;
123 else { c = *from++;
124 switch (c) {
125 case '0' : *to++ = RUB;
126 break;
127 case 't' : *to++ = '\t';
128 break;
129 case 'n' : *to++ = '\n';
130 break;
131 default : *to++ = c;
132 break;
133 }
134 }
135 } while (c) ;
136return(--i);
137}