bgets()
[unix-history] / usr / src / usr.bin / tr / tr.c
CommitLineData
14db73f8
BJ
1static char *sccsid = "@(#)tr.c 4.1 (Berkeley) %G%";
2#include <stdio.h>
3
4/* tr - transliterate data stream */
5int dflag = 0;
6int sflag = 0;
7int cflag = 0;
8int save = 0;
9char code[256];
10char squeez[256];
11char vect[256];
12struct string { int last, max; char *p; } string1, string2;
13
14main(argc,argv)
15char **argv;
16{
17 register i;
18 int j;
19 register c, d;
20 char *compl;
21 int lastd;
22
23 string1.last = string2.last = 0;
24 string1.max = string2.max = 0;
25 string1.p = string2.p = "";
26
27 if(--argc>0) {
28 argv++;
29 if(*argv[0]=='-'&&argv[0][1]!=0) {
30 while(*++argv[0])
31 switch(*argv[0]) {
32 case 'c':
33 cflag++;
34 continue;
35 case 'd':
36 dflag++;
37 continue;
38 case 's':
39 sflag++;
40 continue;
41 }
42 argc--;
43 argv++;
44 }
45 }
46 if(argc>0) string1.p = argv[0];
47 if(argc>1) string2.p = argv[1];
48 for(i=0; i<256; i++)
49 code[i] = vect[i] = 0;
50 if(cflag) {
51 while(c = next(&string1))
52 vect[c&0377] = 1;
53 j = 0;
54 for(i=1; i<256; i++)
55 if(vect[i]==0) vect[j++] = i;
56 vect[j] = 0;
57 compl = vect;
58 }
59 for(i=0; i<256; i++)
60 squeez[i] = 0;
61 lastd = 0;
62 for(;;){
63 if(cflag) c = *compl++;
64 else c = next(&string1);
65 if(c==0) break;
66 d = next(&string2);
67 if(d==0) d = lastd;
68 else lastd = d;
69 squeez[d&0377] = 1;
70 code[c&0377] = dflag?1:d;
71 }
72 while(d = next(&string2))
73 squeez[d&0377] = 1;
74 squeez[0] = 1;
75 for(i=0;i<256;i++) {
76 if(code[i]==0) code[i] = i;
77 else if(dflag) code[i] = 0;
78 }
79
80 while((c=getc(stdin)) != EOF ) {
81 if(c == 0) continue;
82 if(c = code[c&0377]&0377)
83 if(!sflag || c!=save || !squeez[c&0377])
84 putchar(save = c);
85 }
86 exit(0);
87}
88
89next(s)
90struct string *s;
91{
92
93again:
94 if(s->max) {
95 if(s->last++ < s->max)
96 return(s->last);
97 s->max = s->last = 0;
98 }
99 if(s->last && *s->p=='-') {
100 nextc(s);
101 s->max = nextc(s);
102 if(s->max==0) {
103 s->p--;
104 return('-');
105 }
106 if(s->max < s->last) {
107 s->last = s->max-1;
108 return('-');
109 }
110 goto again;
111 }
112 return(s->last = nextc(s));
113}
114
115nextc(s)
116struct string *s;
117{
118 register c, i, n;
119
120 c = *s->p++;
121 if(c=='\\') {
122 i = n = 0;
123 while(i<3 && (c = *s->p)>='0' && c<='7') {
124 n = n*8 + c - '0';
125 i++;
126 s->p++;
127 }
128 if(i>0) c = n;
129 else c = *s->p++;
130 }
131 if(c==0) *--s->p = 0;
132 return(c&0377);
133}