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