/*
a state machine for interpreting big5 (hk format).
*/
void
big5proc(int c, Rune **r, long input_loc)
{
static enum { state0, state1 } state = state0;
static int lastc;
long n, ch, f, cold = c;
switch(state)
{
case state0: /* idle state */
if(c < 0)
return;
if(c >= 0xA1){
lastc = c;
state = state1;
return;
}
if(c == 26)
c = '\n';
emit(c);
return;
case state1: /* seen a font spec */
if(c >= 64 && c <= 126)
c -= 64;
else if(c >= 161 && c <= 254)
c = c-161 + 63;
else {
nerrors++;
if(squawk)
warn("bad big5 glyph (from 0x%x,0x%lx) near byte %ld in %s",
lastc, cold, input_loc, file);
if(!clean)
emit(BADMAP);
state = state0;
return;
}
if(lastc >= 161 && lastc <= 254)
f = lastc - 161;
else {
nerrors++;
if(squawk)
warn("bad big5 font %d (from 0x%x,0x%lx) near byte %ld in %s",
lastc-161, lastc, cold, input_loc, file);
if(!clean)
emit(BADMAP);
state = state0;
return;
}
n = f*BIG5FONT + c;
if(n < BIG5MAX)
ch = tabbig5[n];
else
ch = -1;
if(ch < 0){
nerrors++;
if(squawk)
warn("unknown big5 %ld (from 0x%x,0x%lx) near byte %ld in %s",
n, lastc, cold, input_loc, file);
if(!clean)
emit(BADMAP);
} else
emit(ch);
state = state0;
}
}
void
big5_in(int fd, long *, struct convert *out)
{
Rune ob[N];
Rune *r, *re;
uchar ibuf[N];
int n, i;
long nin;