#ifdef PLAN9 #include #include #include #else #include #include #include "plan9.h" #endif #include "hdr.h" #include "conv.h" #include "ksc.h" /* contributed by kuro@vodka.Eng.Sun.COM (Teruhiko Kurosaka) */ /* a state machine for interpreting shift-ksc. */ #define SS2 0x8e #define SS3 0x8f /* * Convert EUC in Koran locale to Unicode. * Only codeset 0 and 1 are used. */ void ukscproc(int c, Rune **r, long input_loc) { static enum { init, cs1last /*, cs2, cs3first, cs3last*/} state = init; static int korean646 = 1; /* fixed to 1 for now. */ static int lastc; int n; long l; switch(state) { case init: if (c < 0){ return; }else if (c < 128){ if(korean646 && (c=='\\')){ emit(0x20A9); } else { emit(c); } /* }else if (c==SS2){ state = cs2; }else if (c==SS3){ state = cs3first; */ }else{ lastc = c; state = cs1last; } return; case cs1last: /* 2nd byte of codeset 1 (KSC 5601) */ if(c < 0){ if(squawk) EPR "%s: unexpected EOF in %s\n", argv0, file); c = 0x21 | (lastc&0x80); } n = ((lastc&0x7f)-33)*94 + (c&0x7f)-33; if((n >= ksc5601max) || ((l = tabksc5601[n]) < 0)){ nerrors++; if(squawk) EPR "%s: unknown ksc5601 %d (from 0x%x,0x%x) near byte %ld in %s\n", argv0, n, lastc, c, input_loc, file); if(!clean) emit(BADMAP); } else { emit(l); } state = init; return; default: if(squawk) EPR "%s: ukscproc: unknown state %d\n", argv0, init); } } void uksc_in(int fd, long *notused, struct convert *out) { Rune ob[N]; Rune *r, *re; uchar ibuf[N]; int n, i; long nin; USED(notused); r = ob; re = ob+N-3; nin = 0; while((n = read(fd, ibuf, sizeof ibuf)) > 0){ for(i = 0; i < n; i++){ ukscproc(ibuf[i], &r, nin++); if(r >= re){ OUT(out, ob, r-ob); r = ob; } } if(r > ob){ OUT(out, ob, r-ob); r = ob; } } ukscproc(-1, &r, nin); if(r > ob) OUT(out, ob, r-ob); OUT(out, ob, 0); } void uksc_out(Rune *base, int n, long *notused) { char *p; int i; Rune r; long l; static int first = 1; USED(notused); if(first){ first = 0; for(i = 0; i < NRUNE; i++) tab[i] = -1; for(i = 0; i < ksc5601max; i++) if((l = tabksc5601[i]) != -1){ if(l < 0) tab[-l] = i; else tab[l] = i; } } nrunes += n; p = obuf; for(i = 0; i < n; i++){ r = base[i]; if(r < 128) *p++ = r; else { if(tab[r] != -1){ *p++ = 0x80 | (tab[r]/94 + 0x21); *p++ = 0x80 | (tab[r]%94 + 0x21); continue; } if(squawk) EPR "%s: rune 0x%x not in output cs\n", argv0, r); nerrors++; if(clean) continue; *p++ = BYTEBADMAP; } } noutput += p-obuf; if(p > obuf) write(1, obuf, p-obuf); }