ref: 9ced712a2ad70557a8ceb89ff3b969b92c85f68c
dir: /sys/src/cmd/tcs/tune.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "hdr.h" #include "conv.h" typedef struct Tmap Tmap; struct Tmap { Rune u; Rune t; }; static Tmap t1[] = { {0x0b85/*அ*/, 0xe201/**/}, {0x0b86/*ஆ*/, 0xe202/**/}, {0x0b87/*இ*/, 0xe203/**/}, {0x0b88/*ஈ*/, 0xe204/**/}, {0x0b89/*உ*/, 0xe205/**/}, {0x0b8a/*ஊ*/, 0xe206/**/}, {0x0b8e/*எ*/, 0xe207/**/}, {0x0b8f/*ஏ*/, 0xe208/**/}, {0x0b90/*ஐ*/, 0xe209/**/}, {0x0b92/*ஒ*/, 0xe20a/**/}, {0x0b93/*ஓ*/, 0xe20b/**/}, {0x0b94/*ஔ*/, 0xe20c/**/}, {0x0b83/*ஃ*/, 0xe20d/**/} }; static Rune t2[] = { 0x0bcd/*்*/, 0x0bcd/*்*/, // filler 0x0bbe/*ா*/, 0x0bbf/*ி*/, 0x0bc0/*ீ*/, 0x0bc1/*ு*/, 0x0bc2/*ூ*/, 0x0bc6/*ெ*/, 0x0bc7/*ே*/, 0x0bc8/*ை*/, 0x0bca/*ொ*/, 0x0bcb/*ோ*/, 0x0bcc/*ௌ*/ }; static Tmap t3[] = { {0x0b95/*க*/, 0xe211/**/}, {0x0b99/*ங*/, 0xe221/**/}, {0x0b9a/*ச*/, 0xe231/**/}, {0x0b9c/*ஜ*/, 0xe331/**/}, {0x0b9e/*ஞ*/, 0xe241/**/}, {0x0b9f/*ட*/, 0xe251/**/}, {0x0ba3/*ண*/, 0xe261/**/}, {0x0ba4/*த*/, 0xe271/**/}, {0x0ba8/*ந*/, 0xe281/**/}, {0x0ba9/*ன*/, 0xe321/**/}, {0x0baa/*ப*/, 0xe291/**/}, {0x0bae/*ம*/, 0xe2a1/**/}, {0x0baf/*ய*/, 0xe2b1/**/}, {0x0bb0/*ர*/, 0xe2c1/**/}, {0x0bb1/*ற*/, 0xe311/**/}, {0x0bb2/*ல*/, 0xe2d1/**/}, {0x0bb3/*ள*/, 0xe301/**/}, {0x0bb4/*ழ*/, 0xe2f1/**/}, {0x0bb5/*வ*/, 0xe2e1/**/}, {0x0bb6/*ஶ*/, 0xe341/**/}, {0x0bb7/*ஷ*/, 0xe351/**/}, {0x0bb8/*ஸ*/, 0xe361/**/}, {0x0bb9/*ஹ*/, 0xe371/**/} }; static Rune findbytune(Tmap *tab, int size, Rune t) { int i; for(i = 0; i < size; i++) if(tab[i].t == t) return tab[i].u; return Runeerror; } static Rune findbyuni(Tmap *tab, int size, Rune u) { int i; for(i = 0; i < size; i++) if(tab[i].u == u) return tab[i].t; return Runeerror; } static int findindex(Rune *rstr, int size, Rune r) { int i; for(i = 0; i < size; i++) if(rstr[i] == r) return i; return -1; } void tune_in(int fd, long *, struct convert *out) { Biobuf b; Rune *r, *er, tr; int c, i; r = runes; er = runes+N-3; Binit(&b, fd, OREAD); while((c = Bgetrune(&b)) != Beof){ ninput += b.runesize; if(r >= er){ OUT(out, runes, r-runes); r = runes; } if(c>=0xe210/**/ && c <= 0xe38c/**/ && (i = c%16) < nelem(t2)){ if(c >= 0xe380/**/){ *r++ = 0x0b95/*க*/; *r++ = 0x0bcd/*்*/; *r++ = 0x0bb7/*ஷ*/; }else *r++ = findbytune(t3, nelem(t3), c-i+1); if(i != 1) *r++ = t2[i]; }else if((tr = findbytune(t1, nelem(t1), c)) != Runeerror) *r++ = tr; else switch(c){ case 0xe3d0/**/: *r++ = 0x0ba3/*ண*/; *r++ = 0x0bbe/*ா*/; break; case 0xe3d1/**/: *r++ = 0x0bb1/*ற*/; *r++ = 0x0bbe/*ா*/; break; case 0xe3d2/**/: *r++ = 0x0ba9/*ன*/; *r++ = 0x0bbe/*ா*/; break; case 0xe3d4/**/: *r++ = 0x0ba3/*ண*/; *r++ = 0x0bc8/*ை*/; break; case 0xe3d5/**/: *r++ = 0x0bb2/*ல*/; *r++ = 0x0bc8/*ை*/; break; case 0xe3d6/**/: *r++ = 0x0bb3/*ள*/; *r++ = 0x0bc8/*ை*/; break; case 0xe3d7/**/: *r++ = 0x0ba9/*ன*/; *r++ = 0x0bc8/*ை*/; break; case 0xe38d/**/: *r++ = 0x0bb6/*ஶ*/; *r++ = 0x0bcd/*்*/; *r++ = 0x0bb0/*ர*/; *r++ = 0x0bc0/*ீ*/; break; default: if(c >= 0xe200 && c <= 0xe3ff){ if(squawk) warn("rune 0x%x not in output cs", c); nerrors++; if(clean) break; c = BADMAP; } *r++ = c; break; } } if(r > runes) OUT(out, runes, r-runes); OUT(out, runes, 0); } void tune_out(Rune *r, int n, long *) { static int state = 0; static Rune lastr; Rune *er, tr, rr; char *p; int i; nrunes += n; er = r+n; for(p = obuf; r < er; r++){ switch(state){ case 0: case0: if((tr = findbyuni(t3, nelem(t3), *r)) != Runeerror){ lastr = tr; state = 1; }else if(*r == 0x0b92/*ஒ*/){ lastr = 0xe20a/**/; state = 3; }else if((tr = findbyuni(t1, nelem(t1), *r)) != Runeerror) p += runetochar(p, &tr); else p += runetochar(p, r); break; case 1: case1: if((i = findindex(t2, nelem(t2), *r)) != -1){ if(lastr && lastr != Runeerror) lastr += i-1; if(*r ==0x0bc6/*ெ*/) state = 5; else if(*r ==0x0bc7/*ே*/) state = 4; else if(lastr == 0xe210/**/) state = 2; else if(lastr == 0xe340/**/) state = 6; else{ if(lastr) p += runetochar(p, &lastr); state = 0; } }else if(lastr && lastr != Runeerror && (*r == 0x00b2/*²*/ || *r == 0x00b3/*³*/ || *r == 0x2074/*⁴*/)){ if(squawk) warn("character <U+%.4X, U+%.4X> not in output cs", lastr, *r); lastr = clean ? 0 : Runeerror; nerrors++; }else{ if(lastr) p += runetochar(p, &lastr); state = 0; goto case0; } break; case 2: if(*r == 0x0bb7/*ஷ*/){ lastr = 0xe381/**/; state = 1; break; } p += runetochar(p, &lastr); state = 0; goto case0; case 3: state = 0; if(*r == 0x0bd7/*ௗ*/){ rr = 0xe20c/**/; p += runetochar(p, &rr); break; } p += runetochar(p, &lastr); goto case0; case 4: state = 0; if(*r == 0x0bbe/*ா*/){ if(lastr){ if(lastr != Runeerror) lastr += 3; p += runetochar(p, &lastr); } break; } if(lastr) p += runetochar(p, &lastr); goto case0; case 5: state = 0; if(*r == 0x0bbe/*ா*/ || *r == 0x0bd7/*ௗ*/){ if(lastr){ if(lastr != Runeerror) lastr += *r == 0x0bbe/*ா*/ ? 3 : 5; p += runetochar(p, &lastr); } break; } if(lastr) p += runetochar(p, &lastr); goto case0; case 6: if(*r == 0x0bb0/*ர*/){ state = 7; break; } p += runetochar(p, &lastr); state = 0; goto case0; case 7: if(*r == 0x0bc0/*ீ*/){ rr = 0xe38d/**/; p += runetochar(p, &rr); state = 0; break; } p += runetochar(p, &lastr); lastr = 0xe2c1/**/; state = 1; goto case1; } } if(n == 0 && state != 0){ if(lastr) p += runetochar(p, &lastr); state = 0; } noutput += p-obuf; if(p > obuf) write(1, obuf, p-obuf); }