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