conv_ksc.c (2733B)
1 #ifdef PLAN9 2 #include <u.h> 3 #include <libc.h> 4 #include <bio.h> 5 #else 6 #include <stdio.h> 7 #include <unistd.h> 8 #include "plan9.h" 9 #endif 10 #include "hdr.h" 11 #include "conv.h" 12 #include "ksc.h" 13 14 /* 15 contributed by kuro@vodka.Eng.Sun.COM (Teruhiko Kurosaka) 16 */ 17 18 /* 19 a state machine for interpreting shift-ksc. 20 */ 21 22 #define SS2 0x8e 23 #define SS3 0x8f 24 /* 25 * Convert EUC in Koran locale to Unicode. 26 * Only codeset 0 and 1 are used. 27 */ 28 void 29 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; 36 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; 57 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 } 82 83 void 84 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; 91 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 OUT(out, ob, 0); 113 } 114 115 void 116 uksc_out(Rune *base, int n, long *notused) 117 { 118 char *p; 119 int i; 120 Rune r; 121 long l; 122 static int first = 1; 123 124 USED(notused); 125 if(first){ 126 first = 0; 127 for(i = 0; i < NRUNE; i++) 128 tab[i] = -1; 129 for(i = 0; i < ksc5601max; i++) 130 if((l = tabksc5601[i]) != -1){ 131 if(l < 0) 132 tab[-l] = i; 133 else 134 tab[l] = i; 135 } 136 } 137 nrunes += n; 138 p = obuf; 139 for(i = 0; i < n; i++){ 140 r = base[i]; 141 if(r < 128) 142 *p++ = r; 143 else { 144 if(tab[r] != -1){ 145 *p++ = 0x80 | (tab[r]/94 + 0x21); 146 *p++ = 0x80 | (tab[r]%94 + 0x21); 147 continue; 148 } 149 if(squawk) 150 EPR "%s: rune 0x%x not in output cs\n", argv0, r); 151 nerrors++; 152 if(clean) 153 continue; 154 *p++ = BYTEBADMAP; 155 } 156 } 157 noutput += p-obuf; 158 if(p > obuf) 159 write(1, obuf, p-obuf); 160 }