ref: e2566e93e871e288a8a3865585cf53072c53d047
dir: /sys/src/cmd/tcs/conv_ksc.c/
#include <u.h> #include <libc.h> #include <bio.h> #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) warn("unexpected EOF in %s", file); c = 0x21 | (lastc&0x80); } n = ((lastc&0x7f)-33)*94 + (c&0x7f)-33; if((n >= ksc5601max) || ((l = tabksc5601[n]) < 0)){ nerrors++; if(squawk) warn("unknown ksc5601 %d (from 0x%x,0x%x) near byte %ld in %s", n, lastc, c, input_loc, file); if(!clean) emit(BADMAP); } else { emit(l); } state = init; return; default: if(squawk) warn("ukscproc: unknown state %d", init); } } void uksc_in(int fd, long *, struct convert *out) { Rune ob[N]; Rune *r, *re; uchar ibuf[N]; int n, i; long nin; 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 *) { char *p; int i; Rune r; long l; static int first = 1; 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(r < NRUNE && tab[r] != -1){ *p++ = 0x80 | (tab[r]/94 + 0x21); *p++ = 0x80 | (tab[r]%94 + 0x21); continue; } if(squawk) warn("rune 0x%x not in output cs", r); nerrors++; if(clean) continue; *p++ = BYTEBADMAP; } } noutput += p-obuf; if(p > obuf) write(1, obuf, p-obuf); }