xref: /plan9/sys/src/cmd/dict/world.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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
worldprintentry(Entry e,int cmd)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
worldnextoff(long fromoff)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
putchar(int c,int * state)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
worldprintkey(void)181 worldprintkey(void)
182 {
183 	Bprint(bout, "No pronunciation key.\n");
184 }
185