]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/tcs/conv_ksc.c
kernel: keep segment locked for data2txt
[plan9front.git] / sys / src / cmd / tcs / conv_ksc.c
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 }
161