1219b2ee8SDavid du Colombier #ifdef PLAN9
2219b2ee8SDavid du Colombier #include <u.h>
3219b2ee8SDavid du Colombier #include <libc.h>
4219b2ee8SDavid du Colombier #include <bio.h>
5219b2ee8SDavid du Colombier #else
6219b2ee8SDavid du Colombier #include <stdio.h>
7219b2ee8SDavid du Colombier #include <unistd.h>
8219b2ee8SDavid du Colombier #include "plan9.h"
9219b2ee8SDavid du Colombier #endif
10219b2ee8SDavid du Colombier #include "hdr.h"
11219b2ee8SDavid du Colombier #include "conv.h"
12219b2ee8SDavid du Colombier #include "ksc.h"
13219b2ee8SDavid du Colombier
14219b2ee8SDavid du Colombier /*
15219b2ee8SDavid du Colombier contributed by kuro@vodka.Eng.Sun.COM (Teruhiko Kurosaka)
16219b2ee8SDavid du Colombier */
17219b2ee8SDavid du Colombier
18219b2ee8SDavid du Colombier /*
19219b2ee8SDavid du Colombier a state machine for interpreting shift-ksc.
20219b2ee8SDavid du Colombier */
21219b2ee8SDavid du Colombier
22219b2ee8SDavid du Colombier #define SS2 0x8e
23219b2ee8SDavid du Colombier #define SS3 0x8f
24219b2ee8SDavid du Colombier /*
25219b2ee8SDavid du Colombier * Convert EUC in Koran locale to Unicode.
26219b2ee8SDavid du Colombier * Only codeset 0 and 1 are used.
27219b2ee8SDavid du Colombier */
28219b2ee8SDavid du Colombier void
ukscproc(int c,Rune ** r,long input_loc)29219b2ee8SDavid du Colombier ukscproc(int c, Rune **r, long input_loc)
30219b2ee8SDavid du Colombier {
31219b2ee8SDavid du Colombier static enum { init, cs1last /*, cs2, cs3first, cs3last*/} state = init;
32219b2ee8SDavid du Colombier static int korean646 = 1; /* fixed to 1 for now. */
33219b2ee8SDavid du Colombier static int lastc;
34219b2ee8SDavid du Colombier int n;
35219b2ee8SDavid du Colombier long l;
36219b2ee8SDavid du Colombier
37219b2ee8SDavid du Colombier switch(state)
38219b2ee8SDavid du Colombier {
39219b2ee8SDavid du Colombier case init:
40219b2ee8SDavid du Colombier if (c < 0){
41219b2ee8SDavid du Colombier return;
42219b2ee8SDavid du Colombier }else if (c < 128){
43219b2ee8SDavid du Colombier if(korean646 && (c=='\\')){
44219b2ee8SDavid du Colombier emit(0x20A9);
45219b2ee8SDavid du Colombier } else {
46219b2ee8SDavid du Colombier emit(c);
47219b2ee8SDavid du Colombier }
48219b2ee8SDavid du Colombier /* }else if (c==SS2){
49219b2ee8SDavid du Colombier state = cs2;
50219b2ee8SDavid du Colombier }else if (c==SS3){
51219b2ee8SDavid du Colombier state = cs3first;
52219b2ee8SDavid du Colombier */ }else{
53219b2ee8SDavid du Colombier lastc = c;
54219b2ee8SDavid du Colombier state = cs1last;
55219b2ee8SDavid du Colombier }
56219b2ee8SDavid du Colombier return;
57219b2ee8SDavid du Colombier
58219b2ee8SDavid du Colombier case cs1last: /* 2nd byte of codeset 1 (KSC 5601) */
59219b2ee8SDavid du Colombier if(c < 0){
60219b2ee8SDavid du Colombier if(squawk)
61219b2ee8SDavid du Colombier EPR "%s: unexpected EOF in %s\n", argv0, file);
62219b2ee8SDavid du Colombier c = 0x21 | (lastc&0x80);
63219b2ee8SDavid du Colombier }
64219b2ee8SDavid du Colombier n = ((lastc&0x7f)-33)*94 + (c&0x7f)-33;
65219b2ee8SDavid du Colombier if((n >= ksc5601max) || ((l = tabksc5601[n]) < 0)){
66219b2ee8SDavid du Colombier nerrors++;
67219b2ee8SDavid du Colombier if(squawk)
68219b2ee8SDavid du Colombier EPR "%s: unknown ksc5601 %d (from 0x%x,0x%x) near byte %ld in %s\n", argv0, n, lastc, c, input_loc, file);
69219b2ee8SDavid du Colombier if(!clean)
70219b2ee8SDavid du Colombier emit(BADMAP);
71219b2ee8SDavid du Colombier } else {
72219b2ee8SDavid du Colombier emit(l);
73219b2ee8SDavid du Colombier }
74219b2ee8SDavid du Colombier state = init;
75219b2ee8SDavid du Colombier return;
76219b2ee8SDavid du Colombier default:
77219b2ee8SDavid du Colombier if(squawk)
78219b2ee8SDavid du Colombier EPR "%s: ukscproc: unknown state %d\n",
79219b2ee8SDavid du Colombier argv0, init);
80219b2ee8SDavid du Colombier }
81219b2ee8SDavid du Colombier }
82219b2ee8SDavid du Colombier
83219b2ee8SDavid du Colombier void
uksc_in(int fd,long * notused,struct convert * out)84219b2ee8SDavid du Colombier uksc_in(int fd, long *notused, struct convert *out)
85219b2ee8SDavid du Colombier {
86219b2ee8SDavid du Colombier Rune ob[N];
87219b2ee8SDavid du Colombier Rune *r, *re;
88219b2ee8SDavid du Colombier uchar ibuf[N];
89219b2ee8SDavid du Colombier int n, i;
90219b2ee8SDavid du Colombier long nin;
91219b2ee8SDavid du Colombier
92219b2ee8SDavid du Colombier USED(notused);
93219b2ee8SDavid du Colombier r = ob;
94219b2ee8SDavid du Colombier re = ob+N-3;
95219b2ee8SDavid du Colombier nin = 0;
96219b2ee8SDavid du Colombier while((n = read(fd, ibuf, sizeof ibuf)) > 0){
97219b2ee8SDavid du Colombier for(i = 0; i < n; i++){
98219b2ee8SDavid du Colombier ukscproc(ibuf[i], &r, nin++);
99219b2ee8SDavid du Colombier if(r >= re){
100219b2ee8SDavid du Colombier OUT(out, ob, r-ob);
101219b2ee8SDavid du Colombier r = ob;
102219b2ee8SDavid du Colombier }
103219b2ee8SDavid du Colombier }
104219b2ee8SDavid du Colombier if(r > ob){
105219b2ee8SDavid du Colombier OUT(out, ob, r-ob);
106219b2ee8SDavid du Colombier r = ob;
107219b2ee8SDavid du Colombier }
108219b2ee8SDavid du Colombier }
109219b2ee8SDavid du Colombier ukscproc(-1, &r, nin);
110219b2ee8SDavid du Colombier if(r > ob)
111219b2ee8SDavid du Colombier OUT(out, ob, r-ob);
112*ec46fab0SDavid du Colombier OUT(out, ob, 0);
113219b2ee8SDavid du Colombier }
114219b2ee8SDavid du Colombier
115219b2ee8SDavid du Colombier void
uksc_out(Rune * base,int n,long * notused)116219b2ee8SDavid du Colombier uksc_out(Rune *base, int n, long *notused)
117219b2ee8SDavid du Colombier {
118219b2ee8SDavid du Colombier char *p;
119219b2ee8SDavid du Colombier int i;
120219b2ee8SDavid du Colombier Rune r;
121219b2ee8SDavid du Colombier long l;
122219b2ee8SDavid du Colombier static int first = 1;
123219b2ee8SDavid du Colombier
124219b2ee8SDavid du Colombier USED(notused);
125219b2ee8SDavid du Colombier if(first){
126219b2ee8SDavid du Colombier first = 0;
127219b2ee8SDavid du Colombier for(i = 0; i < NRUNE; i++)
128219b2ee8SDavid du Colombier tab[i] = -1;
129219b2ee8SDavid du Colombier for(i = 0; i < ksc5601max; i++)
130219b2ee8SDavid du Colombier if((l = tabksc5601[i]) != -1){
131219b2ee8SDavid du Colombier if(l < 0)
132219b2ee8SDavid du Colombier tab[-l] = i;
133219b2ee8SDavid du Colombier else
134219b2ee8SDavid du Colombier tab[l] = i;
135219b2ee8SDavid du Colombier }
136219b2ee8SDavid du Colombier }
137219b2ee8SDavid du Colombier nrunes += n;
138219b2ee8SDavid du Colombier p = obuf;
139219b2ee8SDavid du Colombier for(i = 0; i < n; i++){
140219b2ee8SDavid du Colombier r = base[i];
141219b2ee8SDavid du Colombier if(r < 128)
142219b2ee8SDavid du Colombier *p++ = r;
143219b2ee8SDavid du Colombier else {
144219b2ee8SDavid du Colombier if(tab[r] != -1){
145219b2ee8SDavid du Colombier *p++ = 0x80 | (tab[r]/94 + 0x21);
146219b2ee8SDavid du Colombier *p++ = 0x80 | (tab[r]%94 + 0x21);
147219b2ee8SDavid du Colombier continue;
148219b2ee8SDavid du Colombier }
149219b2ee8SDavid du Colombier if(squawk)
150219b2ee8SDavid du Colombier EPR "%s: rune 0x%x not in output cs\n", argv0, r);
151219b2ee8SDavid du Colombier nerrors++;
152219b2ee8SDavid du Colombier if(clean)
153219b2ee8SDavid du Colombier continue;
154219b2ee8SDavid du Colombier *p++ = BYTEBADMAP;
155219b2ee8SDavid du Colombier }
156219b2ee8SDavid du Colombier }
157219b2ee8SDavid du Colombier noutput += p-obuf;
158219b2ee8SDavid du Colombier if(p > obuf)
159219b2ee8SDavid du Colombier write(1, obuf, p-obuf);
160219b2ee8SDavid du Colombier }
161219b2ee8SDavid du Colombier
162