Blob
1 #ifdef PLAN92 #include <u.h>3 #include <libc.h>4 #include <bio.h>5 #else6 #include <stdio.h>7 #include <unistd.h>8 #include "plan9.h"9 #endif10 #include "hdr.h"11 #include "conv.h"12 #include "ksc.h"14 /*15 contributed by kuro@vodka.Eng.Sun.COM (Teruhiko Kurosaka)16 */18 /*19 a state machine for interpreting shift-ksc.20 */22 #define SS2 0x8e23 #define SS3 0x8f24 /*25 * Convert EUC in Koran locale to Unicode.26 * Only codeset 0 and 1 are used.27 */28 void29 ukscproc(int c, Rune **r, long input_loc)30 {31 static enum { init, cs1last /*, cs2, cs3first, cs3last*/} state = init;32 static int korean646 = 1; /* fixed to 1 for now. */33 static int lastc;34 int n;35 long l;37 switch(state)38 {39 case init:40 if (c < 0){41 return;42 }else if (c < 128){43 if(korean646 && (c=='\\')){44 emit(0x20A9);45 } else {46 emit(c);47 }48 /* }else if (c==SS2){49 state = cs2;50 }else if (c==SS3){51 state = cs3first;52 */ }else{53 lastc = c;54 state = cs1last;55 }56 return;58 case cs1last: /* 2nd byte of codeset 1 (KSC 5601) */59 if(c < 0){60 if(squawk)61 EPR "%s: unexpected EOF in %s\n", argv0, file);62 c = 0x21 | (lastc&0x80);63 }64 n = ((lastc&0x7f)-33)*94 + (c&0x7f)-33;65 if((n >= ksc5601max) || ((l = tabksc5601[n]) < 0)){66 nerrors++;67 if(squawk)68 EPR "%s: unknown ksc5601 %d (from 0x%x,0x%x) near byte %ld in %s\n", argv0, n, lastc, c, input_loc, file);69 if(!clean)70 emit(BADMAP);71 } else {72 emit(l);73 }74 state = init;75 return;76 default:77 if(squawk)78 EPR "%s: ukscproc: unknown state %d\n",79 argv0, init);80 }81 }83 void84 uksc_in(int fd, long *notused, struct convert *out)85 {86 Rune ob[N];87 Rune *r, *re;88 uchar ibuf[N];89 int n, i;90 long nin;92 USED(notused);93 r = ob;94 re = ob+N-3;95 nin = 0;96 while((n = read(fd, ibuf, sizeof ibuf)) > 0){97 for(i = 0; i < n; i++){98 ukscproc(ibuf[i], &r, nin++);99 if(r >= re){100 OUT(out, ob, r-ob);101 r = ob;102 }103 }104 if(r > ob){105 OUT(out, ob, r-ob);106 r = ob;107 }108 }109 ukscproc(-1, &r, nin);110 if(r > ob)111 OUT(out, ob, r-ob);112 }114 void115 uksc_out(Rune *base, int n, long *notused)116 {117 char *p;118 int i;119 Rune r;120 long l;121 static int first = 1;123 USED(notused);124 if(first){125 first = 0;126 for(i = 0; i < NRUNE; i++)127 tab[i] = -1;128 for(i = 0; i < ksc5601max; i++)129 if((l = tabksc5601[i]) != -1){130 if(l < 0)131 tab[-l] = i;132 else133 tab[l] = i;134 }135 }136 nrunes += n;137 p = obuf;138 for(i = 0; i < n; i++){139 r = base[i];140 if(r < 128)141 *p++ = r;142 else {143 if(tab[r] != -1){144 *p++ = 0x80 | (tab[r]/94 + 0x21);145 *p++ = 0x80 | (tab[r]%94 + 0x21);146 continue;147 }148 if(squawk)149 EPR "%s: rune 0x%x not in output cs\n", argv0, r);150 nerrors++;151 if(clean)152 continue;153 *p++ = BYTEBADMAP;154 }155 }156 noutput += p-obuf;157 if(p > obuf)158 write(1, obuf, p-obuf);159 }