308 lines
6.1 KiB
C
308 lines
6.1 KiB
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);
|
|
}
|