Blob


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"
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 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;
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 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;
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;
104 if(r > ob){
105 OUT(out, ob, r-ob);
106 r = ob;
109 ukscproc(-1, &r, nin);
110 if(r > ob)
111 OUT(out, ob, r-ob);
112 OUT(out, ob, 0);
115 void
116 uksc_out(Rune *base, int n, long *notused)
118 char *p;
119 int i;
120 Rune r;
121 long l;
122 static int first = 1;
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;
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;
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;
157 noutput += p-obuf;
158 if(p > obuf)
159 write(1, obuf, p-obuf);