xref: /plan9/sys/src/cmd/tcs/tune.c (revision b85a83648eec38fe82b6f00adfd7828ceec5ee8d)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "hdr.h"
5 #include "conv.h"
6 
7 typedef struct Tmap Tmap;
8 struct Tmap
9 {
10 	Rune u;
11 	Rune t;
12 };
13 
14 static Tmap t1[] =
15 {
16 	{0x0b85/*அ*/, 0xe201/**/},
17 	{0x0b86/*ஆ*/, 0xe202/**/},
18 	{0x0b87/*இ*/, 0xe203/**/},
19 	{0x0b88/*ஈ*/, 0xe204/**/},
20 	{0x0b89/*உ*/, 0xe205/**/},
21 	{0x0b8a/*ஊ*/, 0xe206/**/},
22 	{0x0b8e/*எ*/, 0xe207/**/},
23 	{0x0b8f/*ஏ*/, 0xe208/**/},
24 	{0x0b90/*ஐ*/, 0xe209/**/},
25 	{0x0b92/*ஒ*/, 0xe20a/**/},
26 	{0x0b93/*ஓ*/, 0xe20b/**/},
27 	{0x0b94/*ஔ*/, 0xe20c/**/},
28 	{0x0b83/*ஃ*/, 0xe20d/**/}
29 };
30 
31 static Rune t2[] =
32 {
33 	0x0bcd/*்*/,
34 	0x0bcd/*்*/,	// filler
35 	0x0bbe/*ா*/,
36 	0x0bbf/*ி*/,
37 	0x0bc0/*ீ*/,
38 	0x0bc1/*ு*/,
39 	0x0bc2/*ூ*/,
40 	0x0bc6/*ெ*/,
41 	0x0bc7/*ே*/,
42 	0x0bc8/*ை*/,
43 	0x0bca/*ொ*/,
44 	0x0bcb/*ோ*/,
45 	0x0bcc/*ௌ*/
46 };
47 
48 static Tmap t3[] =
49 {
50 	{0x0b95/*க*/, 0xe211/**/},
51 	{0x0b99/*ங*/, 0xe221/**/},
52 	{0x0b9a/*ச*/, 0xe231/**/},
53 	{0x0b9c/*ஜ*/, 0xe331/**/},
54 	{0x0b9e/*ஞ*/, 0xe241/**/},
55 	{0x0b9f/*ட*/, 0xe251/**/},
56 	{0x0ba3/*ண*/, 0xe261/**/},
57 	{0x0ba4/*த*/, 0xe271/**/},
58 	{0x0ba8/*ந*/, 0xe281/**/},
59 	{0x0ba9/*ன*/, 0xe321/**/},
60 	{0x0baa/*ப*/, 0xe291/**/},
61 	{0x0bae/*ம*/, 0xe2a1/**/},
62 	{0x0baf/*ய*/, 0xe2b1/**/},
63 	{0x0bb0/*ர*/, 0xe2c1/**/},
64 	{0x0bb1/*ற*/, 0xe311/**/},
65 	{0x0bb2/*ல*/, 0xe2d1/**/},
66 	{0x0bb3/*ள*/, 0xe301/**/},
67 	{0x0bb4/*ழ*/, 0xe2f1/**/},
68 	{0x0bb5/*வ*/, 0xe2e1/**/},
69  	{0x0bb6/*ஶ*/, 0xe341/**/},
70 	{0x0bb7/*ஷ*/, 0xe351/**/},
71 	{0x0bb8/*ஸ*/, 0xe361/**/},
72 	{0x0bb9/*ஹ*/, 0xe371/**/}
73 };
74 
75 static Rune
findbytune(Tmap * tab,int size,Rune t)76 findbytune(Tmap *tab, int size, Rune t)
77 {
78 	int i;
79 
80 	for(i = 0; i < size; i++)
81 		if(tab[i].t == t)
82 			return tab[i].u;
83 	return Runeerror;
84 }
85 
86 static Rune
findbyuni(Tmap * tab,int size,Rune u)87 findbyuni(Tmap *tab, int size, Rune u)
88 {
89 	int i;
90 
91 	for(i = 0; i < size; i++)
92 		if(tab[i].u == u)
93 			return tab[i].t;
94 	return Runeerror;
95 }
96 
97 static int
findindex(Rune * rstr,int size,Rune r)98 findindex(Rune *rstr, int size, Rune r)
99 {
100 	int i;
101 
102 	for(i = 0; i < size; i++)
103 		if(rstr[i] == r)
104 			return i;
105 	return -1;
106 }
107 
108 void
tune_in(int fd,long * x,struct convert * out)109 tune_in(int fd, long *x, struct convert *out)
110 {
111 	Biobuf b;
112 	Rune rbuf[N];
113 	Rune *r, *er, tr;
114 	int c, i;
115 
116 	USED(x);
117 	r = rbuf;
118 	er = rbuf+N-3;
119 	Binit(&b, fd, OREAD);
120 	while((c = Bgetrune(&b)) != Beof){
121 		ninput += b.runesize;
122 		if(r >= er){
123 			OUT(out, rbuf, r-rbuf);
124 			r = rbuf;
125 		}
126 		if(c>=0xe210/**/ && c <= 0xe38c/**/ && (i = c%16) < nelem(t2)){
127 			if(c >= 0xe380/**/){
128 				*r++ = 0x0b95/*க*/;
129 				*r++ = 0x0bcd/*்*/;
130 				*r++ = 0x0bb7/*ஷ*/;
131 			}else
132 				*r++ = findbytune(t3, nelem(t3), c-i+1);
133 			if(i != 1)
134 				*r++ = t2[i];
135 		}else if((tr = findbytune(t1, nelem(t1), c)) != Runeerror)
136 			*r++ = tr;
137 		else switch(c){
138 			case 0xe3d0/**/:
139 				*r++ = 0x0ba3/*ண*/; *r++ = 0x0bbe/*ா*/;
140 				break;
141 			case 0xe3d1/**/:
142 				*r++ = 0x0bb1/*ற*/; *r++ = 0x0bbe/*ா*/;
143 				break;
144 			case 0xe3d2/**/:
145 				*r++ = 0x0ba9/*ன*/; *r++ = 0x0bbe/*ா*/;
146 				break;
147 			case 0xe3d4/**/:
148 				*r++ = 0x0ba3/*ண*/; *r++ = 0x0bc8/*ை*/;
149 				break;
150 			case 0xe3d5/**/:
151 				*r++ = 0x0bb2/*ல*/; *r++ = 0x0bc8/*ை*/;
152 				break;
153 			case 0xe3d6/**/:
154 				*r++ = 0x0bb3/*ள*/; *r++ = 0x0bc8/*ை*/;
155 				break;
156 			case 0xe3d7/**/:
157 				*r++ = 0x0ba9/*ன*/; *r++ = 0x0bc8/*ை*/;
158 				break;
159 			case 0xe38d/**/:
160 				*r++ = 0x0bb6/*ஶ*/; *r++ = 0x0bcd/*்*/; *r++ = 0x0bb0/*ர*/; *r++ = 0x0bc0/*ீ*/;
161 				break;
162 			default:
163 				if(c >= 0xe200 && c <= 0xe3ff){
164 					if(squawk)
165 						EPR "%s: rune 0x%x not in output cs\n", argv0, c);
166 					nerrors++;
167 					if(clean)
168 						break;
169 					c = BADMAP;
170 				}
171 				*r++ = c;
172 				break;
173 		}
174 	}
175 	if(r > rbuf)
176 		OUT(out, rbuf, r-rbuf);
177 	OUT(out, rbuf, 0);
178 }
179 
180 void
tune_out(Rune * r,int n,long * x)181 tune_out(Rune *r, int n, long *x)
182 {
183 	static int state = 0;
184 	static Rune lastr;
185 	Rune *er, tr, rr;
186 	char *p;
187 	int i;
188 
189 	USED(x);
190 	nrunes += n;
191 	er = r+n;
192 	for(p = obuf; r < er; r++){
193 		switch(state){
194 		case 0:
195 		case0:
196 			if((tr = findbyuni(t3, nelem(t3), *r)) != Runeerror){
197 				lastr = tr;
198 				state = 1;
199 			}else if(*r == 0x0b92/*ஒ*/){
200 				lastr = 0xe20a/**/;
201 				state = 3;
202 			}else if((tr = findbyuni(t1, nelem(t1), *r)) != Runeerror)
203 				p += runetochar(p, &tr);
204 			else
205 				p += runetochar(p, r);
206 			break;
207 		case 1:
208 		case1:
209 			if((i = findindex(t2, nelem(t2), *r)) != -1){
210 				if(lastr && lastr != Runeerror)
211 					lastr += i-1;
212 				if(*r ==0x0bc6/*ெ*/)
213 					state = 5;
214 				else if(*r ==0x0bc7/*ே*/)
215 					state = 4;
216 				else if(lastr == 0xe210/**/)
217 					state = 2;
218 				else if(lastr == 0xe340/**/)
219 					state = 6;
220 				else{
221 					if(lastr)
222 						p += runetochar(p, &lastr);
223 					state = 0;
224 				}
225 			}else if(lastr && lastr != Runeerror && (*r == 0x00b2/*²*/ || *r == 0x00b3/*³*/ || *r == 0x2074/*⁴*/)){
226 				if(squawk)
227 					EPR "%s: character <U+%.4X, U+%.4X> not in output cs\n", argv0, lastr, *r);
228 				lastr = clean ? 0 : Runeerror;
229 				nerrors++;
230 			}else{
231 				if(lastr)
232 					p += runetochar(p, &lastr);
233 				state = 0;
234 				goto case0;
235 			}
236 			break;
237 		case 2:
238 			if(*r == 0x0bb7/*ஷ*/){
239 				lastr = 0xe381/**/;
240 				state = 1;
241 				break;
242 			}
243 			p += runetochar(p, &lastr);
244 			state = 0;
245 			goto case0;
246 		case 3:
247 			state = 0;
248 			if(*r == 0x0bd7/*ௗ*/){
249 				rr = 0xe20c/**/;
250 				p += runetochar(p, &rr);
251 				break;
252 			}
253 			p += runetochar(p, &lastr);
254 			goto case0;
255 		case 4:
256 			state = 0;
257 			if(*r == 0x0bbe/*ா*/){
258 				if(lastr){
259 					if(lastr != Runeerror)
260 						lastr += 3;
261 					p += runetochar(p, &lastr);
262 				}
263 				break;
264 			}
265 			if(lastr)
266 				p += runetochar(p, &lastr);
267 			goto case0;
268 		case 5:
269 			state = 0;
270 			if(*r == 0x0bbe/*ா*/ || *r == 0x0bd7/*ௗ*/){
271 				if(lastr){
272 					if(lastr != Runeerror)
273 						lastr += *r == 0x0bbe/*ா*/ ? 3 : 5;
274 					p += runetochar(p, &lastr);
275 				}
276 				break;
277 			}
278 			if(lastr)
279 				p += runetochar(p, &lastr);
280 			goto case0;
281 		case 6:
282 			if(*r == 0x0bb0/*ர*/){
283 				state = 7;
284 				break;
285 			}
286 			p += runetochar(p, &lastr);
287 			state = 0;
288 			goto case0;
289 		case 7:
290 			if(*r == 0x0bc0/*ீ*/){
291 				rr = 0xe38d/**/;
292 				p += runetochar(p, &rr);
293 				state = 0;
294 				break;
295 			}
296 			p += runetochar(p, &lastr);
297 			lastr = 0xe2c1/**/;
298 			state = 1;
299 			goto case1;
300 		}
301 	}
302 	if(n == 0 && state != 0){
303 		if(lastr)
304 			p += runetochar(p, &lastr);
305 		state = 0;
306 	}
307 	noutput += p-obuf;
308 	write(1, obuf, p-obuf);
309 }
310