]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dict/world.c
cc, ?[acl]: fix gethunk() and move common memory allocator code to cc/compat
[plan9front.git] / sys / src / cmd / dict / world.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
5 #include "kuten.h"
6
7 /*
8  * Routines for handling dictionaries in the "Languages of the World"
9  * format.  worldnextoff *must* be called with <address of valid entry>+1.
10  */
11
12 #define GSHORT(p)       (((p)[0]<<8)|(p)[1])
13
14 static void     putchar(int, int*);
15
16 #define NONE    0xffff
17
18 /* adapted from jhelling@cs.ruu.nl (Jeroen Hellingman) */
19
20 static Rune chartab[] = {
21
22 /*00*/  NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,
23         NONE,   NONE,   L'\n',  L'æ',  L'ø',  L'å',  L'ä',  L'ö',
24 /*10*/  NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,
25         NONE,   NONE,   NONE,   L'Æ',  L'Ø',  L'Å',  L'Ä',  L'Ö',
26
27 /*20*/  L' ',   L'!',   L'"',   L'#',   L'$',   L'%',   L'&',   L'\'',
28         L'(',   L')',   L'*',   L'+',   L',',   L'-',   L'.',   L'/',
29 /*30*/  L'0',   L'1',   L'2',   L'3',   L'4',   L'5',   L'6',   L'7',
30         L'8',   L'9',   L':',   L';',   L'<',   L'=',   L'>',   L'?',
31 /*40*/  L'@',   L'A',   L'B',   L'C',   L'D',   L'E',   L'F',   L'G',
32         L'H',   L'I',   L'J',   L'K',   L'L',   L'M',   L'N',   L'O',
33 /*50*/  L'P',   L'Q',   L'R',   L'S',   L'T',   L'U',   L'V',   L'W',
34         L'X',   L'Y',   L'Z',   L'[',   L'\\',  L']',   L'^',   L'_',
35 /*60*/  L'`',   L'a',   L'b',   L'c',   L'd',   L'e',   L'f',   L'g',
36         L'h',   L'i',   L'j',   L'k',   L'l',   L'm',   L'n',   L'o',
37 /*70*/  L'p',   L'q',   L'r',   L's',   L't',   L'u',   L'v',   L'w',
38         L'x',   L'y',   L'z',   L'{',   L'|',   L'}',   L'~',   NONE,
39
40 /*80*/  L'Ç',  L'ü',  L'é',  L'â',  L'ä',  L'à',  L'å',  L'ç',
41         L'ê',  L'ë',  L'è',  L'ï',  L'î',  L'ì',  L'Ä',  L'Å',
42 /*90*/  L'É',  L'æ',  L'Æ',  L'ô',  L'ö',  L'ò',  L'û',  L'ù',
43         L'ÿ',  L'Ö',  L'Ü',  L'¢',  L'£',  L'¥',  L'₧', L'ʃ',
44 /*a0*/  L'á',  L'í',  L'ó',  L'ú',  L'ñ',  L'Ñ',  L'ª',  L'º',
45         L'¿',  L'⌐', L'¬',  L'½',  L'¼',  L'¡',  L'«',  L'»',
46
47 /*b0*/  L'ɔ',  L'ə',  L'ð',  L'ʃ',  L'ʒ',  L'ŋ',  L'ɑ',  L'z',
48         L'ɪ',  L'ð',  L'ʒ',  L'ã',  L'œ',  L'ũ',  L'ʌ',  L'ɥ',
49 /*c0*/  L'ʀ',  L'ë',  L'l',   L'ʌ',  L'õ',  L'ñ',  L'Œ',  NONE,
50         NONE,   L'S',   L's',   L'Z',   L'z',   NONE,   NONE,   NONE,
51 /*d0*/  L'ß',  NONE,   NONE,   L'ā',  L'ī',  L'ū',  L'ē',  L'ō',  
52         NONE,   NONE,   NONE,   L' ',   NONE,   NONE,   NONE,   NONE,
53
54 /*e0*/  L'α',  L'β',  L'γ',  L'π',  L'Σ',  L'σ',  L'µ',  L'τ',
55         L'Φ',  L'Θ',  L'Ω',  L'δ',  L'∞', L'Ø',  L'ε',  L'∩',
56 /*f0*/  L'≡', L'±',  L'≥', L'≤', L'⌠', L'⌡', L'÷',  L'≈',
57         L'°',  L'∙', L'·',  NONE,   NONE,   NONE,   NONE,   NONE,
58 };
59
60 enum{ Utf, Kanahi, Kanalo=Kanahi+1, GBhi, GBlo=GBhi+1, };
61
62 void
63 worldprintentry(Entry e, int cmd)
64 {
65         int nh, state[3];
66         uchar *p, *pe;
67
68         p = (uchar *)e.start;
69         pe = (uchar *)e.end;
70         nh = GSHORT(p);
71         p += 6;
72         if(cmd == 'h')
73                 pe = p+nh;
74         state[0] = Utf;
75         state[1] = 0;
76         state[2] = 0;
77         while(p < pe){
78                 if(cmd == 'r')
79                         outchar(*p++);
80                 else
81                         putchar(*p++, state);
82         }
83         outnl(0);
84 }
85
86 long
87 worldnextoff(long fromoff)
88 {
89         int nh, np, nd;
90         uchar buf[6];
91
92         if(Bseek(bdict, fromoff-1, 0) < 0)
93                 return -1;
94         if(Bread(bdict, buf, 6) != 6)
95                 return -1;
96         nh = GSHORT(buf);
97         np = GSHORT(buf+2);
98         nd = GSHORT(buf+4);
99         return fromoff-1 + 6 + nh + np + nd;
100 }
101
102 static void
103 putchar(int c, int *state)
104 {
105         int xflag = 0;
106         Rune r;
107         int hi, lo;
108
109         switch(state[0]){
110         case Kanahi:
111         case GBhi:
112                 if(CANS2JH(c) || c == 0xff){
113                         state[0]++;
114                         state[1] = c;
115                         break;
116                 }
117                 /* fall through */
118         case Utf:
119                 if(c == 0xfe){
120                         state[0] = Kanahi;
121                         break;
122                 }else if(c == 0xff){
123                         state[0] = GBhi;
124                         break;
125                 }
126                 r = chartab[c];
127                 if(r < 0x80 && state[2] == 0)
128                         outchar(r);
129                 else if(r == NONE){
130                         switch(c){
131                         case 0xfb:
132                                 if(!xflag){
133                                         state[2] = 1;
134                                         break;
135                                 }
136                         case 0xfc:
137                                 if(!xflag){
138                                         state[2] = 0;
139                                         break;
140                                 }
141                         case 0x10:
142                         case 0xc7: case 0xc8:
143                         case 0xd8: case 0xd9: case 0xda:
144                         case 0xdc: case 0xdd: case 0xde: case 0xdf:
145                         case 0xfd:
146                                 if(!xflag)
147                                         break;
148                                 /* fall through */
149                         default:
150                                 outprint("\\%.2ux", c);
151                         }
152                 }else if(state[2] == 0)
153                         outrune(r);
154                 break;
155         case Kanalo:
156         case GBlo:
157                 if(state[1] == 0xff && c == 0xff){
158                         state[0] = Utf;
159                         break;
160                 }
161                 state[0]--;
162                 hi = state[1];
163                 lo = c;
164                 S2J(hi, lo);            /* convert to JIS */
165                 r = hi*100 + lo - 3232; /* convert to jis208 */
166                 if(state[0] == Kanahi && r < JIS208MAX)
167                         r = tabjis208[r];
168                 else if(state[0] == GBhi && r < GB2312MAX)
169                         r = tabgb2312[r];
170                 else
171                         r = NONE;
172                 if(r == NONE)
173                         outprint("\\%.2ux\\%.2ux", state[1], c);
174                 else
175                         outrune(r);
176                 break;
177         }
178 }
179
180 void
181 worldprintkey(void)
182 {
183         Bprint(bout, "No pronunciation key.\n");
184 }