plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

tune.c (6280B)


      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
     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
     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
     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
    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
    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 }