|
|
1.1 root 1: #include <libc.h>
2:
3: #define N 500
4: typedef unsigned char uchar;
5:
6: uchar from[N];
7: int nfrom;
8: uchar to[N];
9: int nto;
10: uchar trans[256];
11: uchar occur[256];
12: uchar buf[4096];
13:
14: int cflag;
15: int dflag;
16: int sflag;
17:
18: void complement(void);
19: void delete(void);
20: void squeeze(void);
21: void translit(void);
22: void error(char*);
23: int canon(uchar*, uchar*);
24: int getch(uchar**);
25:
26: main(int argc, uchar **argv)
27: {
28: int c;
29: for( ; argc>1 && argv[1][0]=='-'; argc--, argv++){
30: while(c = *++argv[1]){
31: switch(c){
32: case 's':
33: sflag++;
34: continue;
35: case 'd':
36: dflag++;
37: continue;
38: case 'c':
39: cflag++;
40: continue;
41: default:
42: error("bad option");
43: }
44: }
45: }
46: if(argc>1)
47: nfrom = canon(argv[1],from);
48: if(argc>2)
49: nto = canon(argv[2],to);
50: if(argc>3)
51: error("arg count");
52: if(cflag)
53: complement();
54: if(dflag)
55: delete();
56: else
57: translit();
58: return 0;
59: }
60:
61: void
62: delete(void)
63: {
64: int i, c, n, last;
65: uchar *p, *q;
66: for(i=0; i<nfrom; i++)
67: if(c=from[i])
68: trans[c] = 1;
69: if(sflag)
70: for(i=0; i<nto; i++)
71: occur[to[i]] = 1;
72: last = -1;
73: while((n=read(0, buf, sizeof buf)) > 0){
74: for(p=q=buf; --n>=0;){
75: c = *p++;
76: if(!trans[c] && (c!=last || !occur[c]))
77: *q++ = last = c;
78: }
79: if(write(1, buf, q-buf) != q-buf)
80: error("write error");
81: }
82: }
83:
84: void
85: translit(void)
86: {
87: int i, n, c;
88: uchar *p;
89: if(nfrom>0 && nto==0)
90: error("arg count");
91: for(i=0; i<sizeof trans; i++)
92: trans[i] = i;
93: for(i=0; i<nfrom; i++) {
94: n = from[i];
95: c = to[i<nto? i: nto-1];
96: if(occur[n] && trans[n]!=c)
97: error("ambiguous translation");
98: trans[n] = c;
99: occur[n] = 1;
100: }
101: memset(occur,0,sizeof occur);
102: if(sflag)
103: squeeze();
104: else
105: while((n=read(0, buf, sizeof buf)) > 0){
106: for(p=buf; --n>=0; p++)
107: *p = trans[*p];
108: if(write(1, buf, p-buf) != p-buf)
109: error("write error");
110: }
111: }
112:
113: void
114: squeeze(void)
115: {
116: int i, n, c, last;
117: uchar *p, *q;
118: for(i=0; i<nto; i++)
119: occur[to[i]] = 1;
120: last = -1;
121: while((n=read(0, buf, sizeof buf)) > 0){
122: for(p=q=buf; --n>=0;){
123: c = *p++;
124: if((c=trans[c]) != last || !occur[c])
125: *q++ = last = c;
126: }
127: if(write(1, buf, q-buf) != q-buf)
128: error("write error");
129: }
130: }
131:
132: void
133: complement(void)
134: {
135: int i;
136: for(i=0; i<nfrom; i++)
137: occur[from[i]] = 1;
138: for(i=nfrom=0; i<sizeof occur; i++)
139: if(!occur[i])
140: from[nfrom++] = i;
141: memset(occur,0,sizeof occur);
142: }
143:
144: int
145: getch(uchar **ps)
146: {
147: uchar *s = *ps;
148: int c = *s++;
149: int n, i;
150: if(c=='\\' && *s){
151: n = 0;
152: for(i=0; i<3; i++)
153: if(*s>='0' && *s<='7')
154: n = 8*n + *s++ - '0';
155: else
156: break;
157: if(i == 0)
158: c = *s;
159: else if(n <= 0377)
160: c = n;
161: else
162: error("char>0377");
163: }
164: *ps = s;
165: return c;
166: }
167:
168: int
169: canon(uchar *s, uchar *t)
170: {
171: int n = 0;
172: int i, c;
173: while(*s && n<N){
174: if(*s=='-' && n>0 && s[1]){
175: s++;
176: c = getch(&s);
177: for(i=t[n-1]; ++i<=c && n<N ; )
178: t[n++] = i;
179: } else
180: t[n++] = getch(&s);
181: }
182: if(n >= N)
183: error("arg string too long");
184: return n;
185: }
186:
187: void
188: error(char *s)
189: {
190: fprint(2, "tr: %s\n", s);
191: exit(1);
192: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.