| #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 *x, struct convert *out) |
| { |
| Biobuf b; |
| Rune rbuf[N]; |
| Rune *r, *er, tr; |
| int c, i; |
| |
| USED(x); |
| r = rbuf; |
| er = rbuf+N-3; |
| Binit(&b, fd, OREAD); |
| while((c = Bgetrune(&b)) != Beof){ |
| ninput += b.runesize; |
| if(r >= er){ |
| OUT(out, rbuf, r-rbuf); |
| r = rbuf; |
| } |
| 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) |
| EPR "%s: rune 0x%x not in output cs\n", argv0, c); |
| nerrors++; |
| if(clean) |
| break; |
| c = BADMAP; |
| } |
| *r++ = c; |
| break; |
| } |
| } |
| if(r > rbuf) |
| OUT(out, rbuf, r-rbuf); |
| OUT(out, rbuf, 0); |
| } |
| |
| void |
| tune_out(Rune *r, int n, long *x) |
| { |
| static int state = 0; |
| static Rune lastr; |
| Rune *er, tr, rr; |
| char *p; |
| int i; |
| |
| USED(x); |
| 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) |
| EPR "%s: character <U+%.4X, U+%.4X> not in output cs\n", argv0, 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; |
| write(1, obuf, p-obuf); |
| } |