#include #include #include #include "hdr.h" #include "conv.h" typedef struct Tmap Tmap; struct Tmap { Rune u; Rune t; }; static Tmap t1[] = { {L'அ', L''}, {L'ஆ', L''}, {L'இ', L''}, {L'ஈ', L''}, {L'உ', L''}, {L'ஊ', L''}, {L'எ', L''}, {L'ஏ', L''}, {L'ஐ', L''}, {L'ஒ', L''}, {L'ஓ', L''}, {L'ஔ', L''}, {L'ஃ', L''} }; static Rune t2[] = { L'்', L'்', // filler L'ா', L'ி', L'ீ', L'ு', L'ூ', L'ெ', L'ே', L'ை', L'ொ', L'ோ', L'ௌ' }; static Tmap t3[] = { {L'க', L''}, {L'ங', L''}, {L'ச', L''}, {L'ஜ', L''}, {L'ஞ', L''}, {L'ட', L''}, {L'ண', L''}, {L'த', L''}, {L'ந', L''}, {L'ன', L''}, {L'ப', L''}, {L'ம', L''}, {L'ய', L''}, {L'ர', L''}, {L'ற', L''}, {L'ல', L''}, {L'ள', L''}, {L'ழ', L''}, {L'வ', L''}, {L'ஶ', L''}, {L'ஷ', L''}, {L'ஸ', L''}, {L'ஹ', L''} }; 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>=L'' && c <= L'' && (i = c%16) < nelem(t2)){ if(c >= L''){ *r++ = L'க'; *r++ = L'்'; *r++ = L'ஷ'; }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 L'': *r++ = L'ண'; *r++ = L'ா'; break; case L'': *r++ = L'ற'; *r++ = L'ா'; break; case L'': *r++ = L'ன'; *r++ = L'ா'; break; case L'': *r++ = L'ண'; *r++ = L'ை'; break; case L'': *r++ = L'ல'; *r++ = L'ை'; break; case L'': *r++ = L'ள'; *r++ = L'ை'; break; case L'': *r++ = L'ன'; *r++ = L'ை'; break; case L'': *r++ = L'ஶ'; *r++ = L'்'; *r++ = L'ர'; *r++ = L'ீ'; 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 enum { state0, state1, state2, state3, state4, state5, state6, state7 } state = state0; static Rune lastr; Rune *er, tr; char *p; int i; USED(x); nrunes += n; er = r+n; for(p = obuf; r < er; r++) switch(state){ case state0: casestate0: if((tr = findbyuni(t3, nelem(t3), *r)) != Runeerror){ lastr = tr; state = state1; }else if(*r == L'ஒ'){ lastr = L''; state = state3; }else if((tr = findbyuni(t1, nelem(t1), *r)) != Runeerror) p += runetochar(p, &tr); else p += runetochar(p, r); break; case state1: casestate1: if((i = findindex(t2, nelem(t2), *r)) != -1){ if(lastr && lastr != L'�') lastr += i-1; if(*r ==L'ெ') state = state5; else if(*r ==L'ே') state = state4; else if(lastr == L'') state = state2; else if(lastr == L'') state = state6; else{ if(lastr) p += runetochar(p, &lastr); state = state0; } }else if(lastr && lastr != L'�' && (*r == L'²' || *r == L'³' || *r == L'⁴')){ if(squawk) EPR( "%s: character not in output cs\n", argv0, lastr, *r); lastr = clean ? 0 : L'�'; nerrors++; }else{ if(lastr) p += runetochar(p, &lastr); state = state0; goto casestate0; } break; case state2: if(*r == L'ஷ'){ lastr = L''; state = state1; break; } p += runetochar(p, &lastr); state = state0; goto casestate0; case state3: state = state0; if(*r == L'ௗ'){ p += runetochar(p, L""); break; } p += runetochar(p, &lastr); goto casestate0; case state4: state = state0; if(*r == L'ா'){ if(lastr){ if(lastr != L'�') lastr += 3; p += runetochar(p, &lastr); } break; } if(lastr) p += runetochar(p, &lastr); goto casestate0; case state5: state = state0; if(*r == L'ா' || *r == L'ௗ'){ if(lastr){ if(lastr != L'�') lastr += *r == L'ா' ? 3 : 5; p += runetochar(p, &lastr); } break; } if(lastr) p += runetochar(p, &lastr); goto casestate0; case state6: if(*r == L'ர'){ state = state7; break; } p += runetochar(p, &lastr); state = state0; goto casestate0; case state7: if(*r == L'ீ'){ p += runetochar(p, L""); state = state0; break; } p += runetochar(p, &lastr); lastr = L''; state = state1; goto casestate1; } if(n == 0 && state != state0){ if(lastr) p += runetochar(p, &lastr); state = state0; } noutput += p-obuf; write(1, obuf, p-obuf); }