diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/tcs/conv_ksc.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/tcs/conv_ksc.c')
-rwxr-xr-x | sys/src/cmd/tcs/conv_ksc.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/sys/src/cmd/tcs/conv_ksc.c b/sys/src/cmd/tcs/conv_ksc.c new file mode 100755 index 000000000..293ffad1a --- /dev/null +++ b/sys/src/cmd/tcs/conv_ksc.c @@ -0,0 +1,161 @@ +#ifdef PLAN9 +#include <u.h> +#include <libc.h> +#include <bio.h> +#else +#include <stdio.h> +#include <unistd.h> +#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); +} + |