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