1 #include <stdio.h>
2 #include "vnkeys.h"
3 #include "ctype.h"
4 #include "vn78.h"
5 
6 
_doinit()7 static _doinit() { /* fill the map--the code is independent of the encoding */
8     /* C0 ASCII section---must be first to be overridden by Vietnamese */
9     _8to7map[C_SOH][0] = C_SOH;
10     _8to7map[C_STX][0] = C_STX;
11     _8to7map[C_ETX][0] = C_ETX;
12     _8to7map[C_EOT][0] = C_EOT;
13     _8to7map[C_ENQ][0] = C_ENQ;
14     _8to7map[C_ACK][0] = C_ACK;
15     _8to7map[C_BEL][0] = C_BEL;
16     _8to7map[C_BS][0] = C_BS;
17     _8to7map[C_HT][0] = C_HT;
18     _8to7map[C_LF][0] = C_LF;
19     _8to7map[C_VT][0] = C_VT;
20     _8to7map[C_FF][0] = C_FF;
21     _8to7map[C_CR][0] = C_CR;
22     _8to7map[C_SO][0] = C_SO;
23     _8to7map[C_SI][0] = C_SI;
24     _8to7map[C_DLE][0] = C_DLE;
25     _8to7map[C_DC1][0] = C_DC1;
26     _8to7map[C_DC2][0] = C_DC2;
27     _8to7map[C_DC3][0] = C_DC3;
28     _8to7map[C_DC4][0] = C_DC4;
29     _8to7map[C_NAK][0] = C_NAK;
30     _8to7map[C_SYN][0] = C_SYN;
31     _8to7map[C_ETB][0] = C_ETB;
32     _8to7map[C_CAN][0] = C_CAN;
33     _8to7map[C_EM][0] = C_EM;
34     _8to7map[C_SUB][0] = C_SUB;
35     _8to7map[C_ESC][0] = C_ESC;
36     _8to7map[C_IS4][0] = C_IS4;
37     _8to7map[C_IS3][0] = C_IS3;
38     _8to7map[C_IS2][0] = C_IS2;
39     _8to7map[C_IS1][0] = C_IS1;
40 
41     /* C0 Vietnamese section */
42     _8to7map[C_A_breve_hook_above][0] = C_A;
43     _8to7map[C_A_breve_hook_above][1] = C_breve;
44     _8to7map[C_A_breve_hook_above][2] = C_hook_above;
45     _8to7map[C_A_breve_tilde][0] = C_A;
46     _8to7map[C_A_breve_tilde][1] = C_breve;
47     _8to7map[C_A_breve_tilde][2] = C_tilde;
48     _8to7map[C_A_circumflex_tilde][0] = C_A;
49     _8to7map[C_A_circumflex_tilde][1] = C_caret;
50     _8to7map[C_A_circumflex_tilde][2] = C_tilde;
51     _8to7map[C_Y_hook_above][0] = C_Y;
52     _8to7map[C_Y_hook_above][1] = C_hook_above;
53     _8to7map[C_y_hook_above/C_IS3][0] = C_y;
54     _8to7map[C_y_hook_above/C_IS3][1] = C_hook_above;
55     _8to7map[C_Y_tilde][0] = C_Y;
56     _8to7map[C_Y_tilde][1] = C_tilde;
57     _8to7map[C_Y_dot_below][0] = C_Y;
58     _8to7map[C_Y_dot_below][1] = C_dot_below;
59 
60     _8to7map[C_space][0] = C_space;
61     _8to7map[C_exclamation_mark][0] = C_exclamation_mark;
62     _8to7map[C_quotation_mark][0] = C_quotation_mark;
63     _8to7map[C_pound_sign][0] = C_pound_sign;
64     _8to7map[C_dollar_sign][0] = C_dollar_sign;
65     _8to7map[C_percent][0] = C_percent;
66     _8to7map[C_ampersand][0] = C_ampersand;
67     _8to7map[C_apostrophe][0] = C_apostrophe;
68     _8to7map[C_left_parenthesis][0] = C_left_parenthesis;
69     _8to7map[C_right_parenthesis][0] = C_right_parenthesis;
70     _8to7map[C_asterisk][0] = C_asterisk;
71     _8to7map[C_plus_sign][0] = C_plus_sign;
72     _8to7map[C_comma][0] = C_comma;
73     _8to7map[C_hyphen][0] = C_hyphen;
74     _8to7map[C_period][0] = C_period;
75     _8to7map[C_slash][0] = C_slash;
76 
77     _8to7map[C_zero][0] = C_zero;
78     _8to7map[C_one][0] = C_one;
79     _8to7map[C_two][0] = C_two;
80     _8to7map[C_three][0] = C_three;
81     _8to7map[C_four][0] = C_four;
82     _8to7map[C_five][0] = C_five;
83     _8to7map[C_six][0] = C_six;
84     _8to7map[C_seven][0] = C_seven;
85     _8to7map[C_eight][0] = C_eight;
86     _8to7map[C_nine][0] = C_nine;
87 
88     _8to7map[C_colon][0] = C_colon;
89     _8to7map[C_semicolon][0] = C_semicolon;
90     _8to7map[C_less_than][0] = C_less_than;
91     _8to7map[C_equals_sign][0] = C_equals_sign;
92     _8to7map[C_greater_than][0] = C_greater_than;
93     _8to7map[C_hook_above][0] = C_hook_above;
94     _8to7map[C_commercial_at][0] = C_commercial_at;
95 
96     _8to7map[C_A][0] = C_A;
97     _8to7map[C_B][0] = C_B;
98     _8to7map[C_C][0] = C_C;
99     _8to7map[C_D][0] = C_D;
100     _8to7map[C_E][0] = C_E;
101     _8to7map[C_F][0] = C_F;
102     _8to7map[C_G][0] = C_G;
103     _8to7map[C_H][0] = C_H;
104     _8to7map[C_I][0] = C_I;
105     _8to7map[C_J][0] = C_J;
106     _8to7map[C_K][0] = C_K;
107     _8to7map[C_L][0] = C_L;
108     _8to7map[C_M][0] = C_M;
109     _8to7map[C_N][0] = C_N;
110     _8to7map[C_O][0] = C_O;
111     _8to7map[C_P][0] = C_P;
112     _8to7map[C_Q][0] = C_Q;
113     _8to7map[C_R][0] = C_R;
114     _8to7map[C_S][0] = C_S;
115     _8to7map[C_T][0] = C_T;
116     _8to7map[C_U][0] = C_U;
117     _8to7map[C_V][0] = C_V;
118     _8to7map[C_W][0] = C_W;
119     _8to7map[C_X][0] = C_X;
120     _8to7map[C_Y][0] = C_Y;
121     _8to7map[C_Z][0] = C_Z;
122 
123     _8to7map[C_left_square_bracket][0] = C_left_square_bracket;
124     _8to7map[C_back_slash][0] = C_back_slash;
125     _8to7map[C_right_square_bracket][0] = C_right_square_bracket;
126     _8to7map[C_caret][0] = C_caret;
127     _8to7map[C_underscore][0] = C_underscore;
128     _8to7map[C_backquote][0] = C_backquote;
129 
130     _8to7map[C_a][0] = C_a;
131     _8to7map[C_b][0] = C_b;
132     _8to7map[C_c][0] = C_c;
133     _8to7map[C_d][0] = C_d;
134     _8to7map[C_e][0] = C_e;
135     _8to7map[C_f][0] = C_f;
136     _8to7map[C_g][0] = C_g;
137     _8to7map[C_h][0] = C_h;
138     _8to7map[C_i][0] = C_i;
139     _8to7map[C_j][0] = C_j;
140     _8to7map[C_k][0] = C_k;
141     _8to7map[C_l][0] = C_l;
142     _8to7map[C_m][0] = C_m;
143     _8to7map[C_n][0] = C_n;
144     _8to7map[C_o][0] = C_o;
145     _8to7map[C_p][0] = C_p;
146     _8to7map[C_q][0] = C_q;
147     _8to7map[C_r][0] = C_r;
148     _8to7map[C_s][0] = C_s;
149     _8to7map[C_t][0] = C_t;
150     _8to7map[C_u][0] = C_u;
151     _8to7map[C_v][0] = C_v;
152     _8to7map[C_w][0] = C_w;
153     _8to7map[C_x][0] = C_x;
154     _8to7map[C_y][0] = C_y;
155     _8to7map[C_z][0] = C_z;
156 
157     _8to7map[C_left_brace][0] = C_left_brace;
158     _8to7map[C_vertical_bar][0] = C_vertical_bar;
159     _8to7map[C_right_brace][0] = C_right_brace;
160     _8to7map[C_tilde][0] = C_tilde;
161     _8to7map[C_delete][0] = C_delete;
162 
163     /* C1 & G1 Vietnamese section */
164     _8to7map[C_A_hook_above][0] = C_A;
165     _8to7map[C_A_hook_above][1] = C_hook_above;
166     _8to7map[C_A_dot_below][0] = C_A;
167     _8to7map[C_A_dot_below][1] = C_dot_below;
168     _8to7map[C_A_breve][0] = C_A;
169     _8to7map[C_A_breve][1] = C_breve;
170     _8to7map[C_A_breve_acute][0] = C_A;
171     _8to7map[C_A_breve_acute][1] = C_breve;
172     _8to7map[C_A_breve_acute][2] = C_acute;
173     _8to7map[C_A_breve_grave][0] = C_A;
174     _8to7map[C_A_breve_grave][1] = C_breve;
175     _8to7map[C_A_breve_grave][2] = C_grave;
176     _8to7map[C_A_breve_dot_below][0] = C_A;
177     _8to7map[C_A_breve_dot_below][1] = C_breve;
178     _8to7map[C_A_breve_dot_below][2] = C_dot_below;
179     _8to7map[C_A_circumflex_acute][0] = C_A;
180     _8to7map[C_A_circumflex_acute][1] = C_circumflex;
181     _8to7map[C_A_circumflex_acute][2] = C_acute;
182     _8to7map[C_A_circumflex_grave][0] = C_A;
183     _8to7map[C_A_circumflex_grave][1] = C_circumflex;
184     _8to7map[C_A_circumflex_grave][2] = C_grave;
185     _8to7map[C_A_circumflex_hook_above][0] = C_A;
186     _8to7map[C_A_circumflex_hook_above][1] = C_circumflex;
187     _8to7map[C_A_circumflex_hook_above][2] = C_hook_above;
188     _8to7map[C_A_circumflex_dot_below][0] = C_A;
189     _8to7map[C_A_circumflex_dot_below][1] = C_circumflex;
190     _8to7map[C_A_circumflex_dot_below][2] = C_dot_below;
191     _8to7map[C_E_hook_above][0] = C_E;
192     _8to7map[C_E_hook_above][1] = C_hook_above;
193     _8to7map[C_E_tilde][0] = C_E;
194     _8to7map[C_E_tilde][1] = C_tilde;
195     _8to7map[C_E_dot_below][0] = C_E;
196     _8to7map[C_E_dot_below][1] = C_dot_below;
197     _8to7map[C_E_circumflex_acute][0] = C_E;
198     _8to7map[C_E_circumflex_acute][1] = C_circumflex;
199     _8to7map[C_E_circumflex_acute][2] = C_acute;
200     _8to7map[C_E_circumflex_grave][0] = C_E;
201     _8to7map[C_E_circumflex_grave][1] = C_circumflex;
202     _8to7map[C_E_circumflex_grave][2] = C_grave;
203     _8to7map[C_E_circumflex_hook_above][0] = C_E;
204     _8to7map[C_E_circumflex_hook_above][1] = C_circumflex;
205     _8to7map[C_E_circumflex_hook_above][2] = C_hook_above;
206     _8to7map[C_E_circumflex_tilde][0] = C_E;
207     _8to7map[C_E_circumflex_tilde][1] = C_circumflex;
208     _8to7map[C_E_circumflex_tilde][2] = C_tilde;
209     _8to7map[C_E_circumflex_dot_below][0] = C_E;
210     _8to7map[C_E_circumflex_dot_below][1] = C_circumflex;
211     _8to7map[C_E_circumflex_dot_below][2] = C_dot_below;
212     _8to7map[C_I_hook_above][0] = C_I;
213     _8to7map[C_I_hook_above][1] = C_hook_above;
214     _8to7map[C_I_tilde][0] = C_I;
215     _8to7map[C_I_tilde][1] = C_tilde;
216     _8to7map[C_I_dot_below][0] = C_I;
217     _8to7map[C_I_dot_below][1] = C_dot_below;
218     _8to7map[C_O_hook_above][0] = C_O;
219     _8to7map[C_O_hook_above][1] = C_hook_above;
220     _8to7map[C_O_dot_below][0] = C_O;
221     _8to7map[C_O_dot_below][1] = C_dot_below;
222     _8to7map[C_O_circumflex_acute][0] = C_O;
223     _8to7map[C_O_circumflex_acute][1] = C_circumflex;
224     _8to7map[C_O_circumflex_acute][2] = C_acute;
225     _8to7map[C_O_circumflex_grave][0] = C_O;
226     _8to7map[C_O_circumflex_grave][1] = C_circumflex;
227     _8to7map[C_O_circumflex_grave][2] = C_grave;
228     _8to7map[C_O_circumflex_hook_above][0] = C_O;
229     _8to7map[C_O_circumflex_hook_above][1] = C_circumflex;
230     _8to7map[C_O_circumflex_hook_above][2] = C_hook_above;
231     _8to7map[C_O_circumflex_tilde][0] = C_O;
232     _8to7map[C_O_circumflex_tilde][1] = C_circumflex;
233     _8to7map[C_O_circumflex_tilde][2] = C_tilde;
234     _8to7map[C_O_circumflex_dot_below][0] = C_O;
235     _8to7map[C_O_circumflex_dot_below][1] = C_circumflex;
236     _8to7map[C_O_circumflex_dot_below][2] = C_dot_below;
237     _8to7map[C_O_horn][0] = C_O;
238     _8to7map[C_O_horn][1] = C_horn;
239     _8to7map[C_O_horn_acute][0] = C_O;
240     _8to7map[C_O_horn_acute][1] = C_horn;
241     _8to7map[C_O_horn_acute][2] = C_acute;
242     _8to7map[C_O_horn_grave][0] = C_O;
243     _8to7map[C_O_horn_grave][1] = C_horn;
244     _8to7map[C_O_horn_grave][2] = C_grave;
245     _8to7map[C_O_horn_hook_above][0] = C_O;
246     _8to7map[C_O_horn_hook_above][1] = C_horn;
247     _8to7map[C_O_horn_hook_above][2] = C_hook_above;
248 
249     _8to7map[C_a_hook_above][0] = C_a;
250     _8to7map[C_a_hook_above][1] = C_hook_above;
251     _8to7map[C_a_dot_below][0] = C_a;
252     _8to7map[C_a_dot_below][1] = C_dot_below;
253     _8to7map[C_a_breve][0] = C_a;
254     _8to7map[C_a_breve][1] = C_breve;
255     _8to7map[C_a_breve_acute][0] = C_a;
256     _8to7map[C_a_breve_acute][1] = C_breve;
257     _8to7map[C_a_breve_acute][2] = C_acute;
258     _8to7map[C_a_breve_grave][0] = C_a;
259     _8to7map[C_a_breve_grave][1] = C_breve;
260     _8to7map[C_a_breve_grave][2] = C_grave;
261     _8to7map[C_a_breve_dot_below][0] = C_a;
262     _8to7map[C_a_breve_dot_below][1] = C_breve;
263     _8to7map[C_a_breve_dot_below][2] = C_dot_below;
264     _8to7map[C_a_circumflex_acute][0] = C_a;
265     _8to7map[C_a_circumflex_acute][1] = C_circumflex;
266     _8to7map[C_a_circumflex_acute][2] = C_acute;
267     _8to7map[C_a_circumflex_grave][0] = C_a;
268     _8to7map[C_a_circumflex_grave][1] = C_circumflex;
269     _8to7map[C_a_circumflex_grave][2] = C_grave;
270     _8to7map[C_a_circumflex_hook_above][0] = C_a;
271     _8to7map[C_a_circumflex_hook_above][1] = C_circumflex;
272     _8to7map[C_a_circumflex_hook_above][2] = C_hook_above;
273     _8to7map[C_a_circumflex_dot_below][0] = C_a;
274     _8to7map[C_a_circumflex_dot_below][1] = C_circumflex;
275     _8to7map[C_a_circumflex_dot_below][2] = C_dot_below;
276     _8to7map[C_e_hook_above][0] = C_e;
277     _8to7map[C_e_hook_above][1] = C_hook_above;
278     _8to7map[C_e_tilde][0] = C_e;
279     _8to7map[C_e_tilde][1] = C_tilde;
280     _8to7map[C_e_dot_below][0] = C_e;
281     _8to7map[C_e_dot_below][1] = C_dot_below;
282     _8to7map[C_e_circumflex_acute][0] = C_e;
283     _8to7map[C_e_circumflex_acute][1] = C_circumflex;
284     _8to7map[C_e_circumflex_acute][2] = C_acute;
285     _8to7map[C_e_circumflex_grave][0] = C_e;
286     _8to7map[C_e_circumflex_grave][1] = C_circumflex;
287     _8to7map[C_e_circumflex_grave][2] = C_grave;
288     _8to7map[C_e_circumflex_hook_above][0] = C_e;
289     _8to7map[C_e_circumflex_hook_above][1] = C_circumflex;
290     _8to7map[C_e_circumflex_hook_above][2] = C_hook_above;
291     _8to7map[C_e_circumflex_tilde][0] = C_e;
292     _8to7map[C_e_circumflex_tilde][1] = C_circumflex;
293     _8to7map[C_e_circumflex_tilde][2] = C_tilde;
294     _8to7map[C_e_circumflex_dot_below][0] = C_e;
295     _8to7map[C_e_circumflex_dot_below][1] = C_circumflex;
296     _8to7map[C_e_circumflex_dot_below][2] = C_dot_below;
297     _8to7map[C_i_hook_above][0] = C_i;
298     _8to7map[C_i_hook_above][1] = C_hook_above;
299     _8to7map[C_U_horn_tilde][0] = C_U;
300     _8to7map[C_U_horn_tilde][1] = C_horn;
301     _8to7map[C_U_horn_tilde][2] = C_tilde;
302     _8to7map[C_U_horn_dot_below][0] = C_U;
303     _8to7map[C_U_horn_dot_below][1] = C_horn;
304     _8to7map[C_U_horn_dot_below][2] = C_dot_below;
305     _8to7map[C_o_hook_above][0] = C_o;
306     _8to7map[C_o_hook_above][1] = C_hook_above;
307     _8to7map[C_o_dot_below][0] = C_o;
308     _8to7map[C_o_dot_below][1] = C_dot_below;
309     _8to7map[C_o_circumflex_acute][0] = C_o;
310     _8to7map[C_o_circumflex_acute][1] = C_circumflex;
311     _8to7map[C_o_circumflex_acute][2] = C_acute;
312     _8to7map[C_o_circumflex_grave][0] = C_o;
313     _8to7map[C_o_circumflex_grave][1] = C_circumflex;
314     _8to7map[C_o_circumflex_grave][2] = C_grave;
315     _8to7map[C_o_circumflex_hook_above][0] = C_o;
316     _8to7map[C_o_circumflex_hook_above][1] = C_circumflex;
317     _8to7map[C_o_circumflex_hook_above][2] = C_hook_above;
318     _8to7map[C_o_circumflex_tilde][0] = C_o;
319     _8to7map[C_o_circumflex_tilde][1] = C_circumflex;
320     _8to7map[C_o_circumflex_tilde][2] = C_tilde;
321     _8to7map[C_o_circumflex_dot_below][0] = C_o;
322     _8to7map[C_o_circumflex_dot_below][1] = C_circumflex;
323     _8to7map[C_o_circumflex_dot_below][2] = C_dot_below;
324     _8to7map[C_o_horn][0] = C_o;
325     _8to7map[C_o_horn][1] = C_horn;
326     _8to7map[C_o_horn_acute][0] = C_o;
327     _8to7map[C_o_horn_acute][1] = C_horn;
328     _8to7map[C_o_horn_acute][2] = C_acute;
329     _8to7map[C_o_horn_grave][0] = C_o;
330     _8to7map[C_o_horn_grave][1] = C_horn;
331     _8to7map[C_o_horn_grave][2] = C_grave;
332     _8to7map[C_U_horn_hook_above][0] = C_U;
333     _8to7map[C_U_horn_hook_above][1] = C_horn;
334     _8to7map[C_U_horn_hook_above][2] = C_hook_above;
335     _8to7map[C_A_grave][0] = C_A;
336     _8to7map[C_A_grave][1] = C_grave;
337     _8to7map[C_A_acute][0] = C_A;
338     _8to7map[C_A_acute][1] = C_acute;
339     _8to7map[C_A_circumflex][0] = C_A;
340     _8to7map[C_A_circumflex][1] = C_circumflex;
341     _8to7map[C_A_tilde][0] = C_A;
342     _8to7map[C_A_tilde][1] = C_tilde;
343     _8to7map[C_O_horn_tilde][0] = C_O;
344     _8to7map[C_O_horn_tilde][1] = C_horn;
345     _8to7map[C_O_horn_tilde][2] = C_tilde;
346     _8to7map[C_O_horn_dot_below][0] = C_O;
347     _8to7map[C_O_horn_dot_below][1] = C_horn;
348     _8to7map[C_O_horn_dot_below][2] = C_dot_below;
349     _8to7map[C_U_hook_above][0] = C_U;
350     _8to7map[C_U_hook_above][1] = C_hook_above;
351     _8to7map[C_U_tilde][0] = C_U;
352     _8to7map[C_U_tilde][1] = C_tilde;
353     _8to7map[C_E_grave][0] = C_E;
354     _8to7map[C_E_grave][1] = C_grave;
355     _8to7map[C_E_acute][0] = C_E;
356     _8to7map[C_E_acute][1] = C_acute;
357     _8to7map[C_E_circumflex][0] = C_E;
358     _8to7map[C_E_circumflex][1] = C_circumflex;
359     _8to7map[C_U_dot_below][0] = C_U;
360     _8to7map[C_U_dot_below][1] = C_dot_below;
361     _8to7map[C_I_grave][0] = C_I;
362     _8to7map[C_I_grave][1] = C_grave;
363     _8to7map[C_I_acute][0] = C_I;
364     _8to7map[C_I_acute][1] = C_acute;
365     _8to7map[C_U_horn][0] = C_U;
366     _8to7map[C_U_horn][1] = C_horn;
367     _8to7map[C_U_horn_acute][0] = C_U;
368     _8to7map[C_U_horn_acute][1] = C_horn;
369     _8to7map[C_U_horn_acute][2] = C_acute;
370     _8to7map[C_D_bar][0] = C_D;
371     _8to7map[C_D_bar][1] = C_D;
372     _8to7map[C_U_horn_grave][0] = C_U;
373     _8to7map[C_U_horn_grave][1] = C_horn;
374     _8to7map[C_U_horn_grave][2] = C_grave;
375     _8to7map[C_O_grave][0] = C_O;
376     _8to7map[C_O_grave][1] = C_grave;
377     _8to7map[C_O_acute][0] = C_O;
378     _8to7map[C_O_acute][1] = C_acute;
379     _8to7map[C_O_circumflex][0] = C_O;
380     _8to7map[C_O_circumflex][1] = C_circumflex;
381     _8to7map[C_O_tilde][0] = C_O;
382     _8to7map[C_O_tilde][1] = C_tilde;
383     _8to7map[C_o_horn_hook_above][0] = C_o;
384     _8to7map[C_o_horn_hook_above][1] = C_horn;
385     _8to7map[C_o_horn_hook_above][2] = C_hook_above;
386     _8to7map[C_i_tilde][0] = C_i;
387     _8to7map[C_i_tilde][1] = C_tilde;
388     _8to7map[C_i_dot_below][0] = C_i;
389     _8to7map[C_i_dot_below][1] = C_dot_below;
390     _8to7map[C_U_grave][0] = C_U;
391     _8to7map[C_U_grave][1] = C_grave;
392     _8to7map[C_U_acute][0] = C_U;
393     _8to7map[C_U_acute][1] = C_acute;
394     _8to7map[C_Y_grave][0] = C_Y;
395     _8to7map[C_Y_grave][1] = C_grave;
396     _8to7map[C_y_hook_above][0] = C_y;
397     _8to7map[C_y_hook_above][1] = C_hook_above;
398     _8to7map[C_Y_acute][0] = C_Y;
399     _8to7map[C_Y_acute][1] = C_acute;
400     _8to7map[C_y_tilde][0] = C_y;
401     _8to7map[C_y_tilde][1] = C_tilde;
402     _8to7map[C_y_dot_below][0] = C_y;
403     _8to7map[C_y_dot_below][1] = C_dot_below;
404     _8to7map[C_a_grave][0] = C_a;
405     _8to7map[C_a_grave][1] = C_grave;
406     _8to7map[C_a_acute][0] = C_a;
407     _8to7map[C_a_acute][1] = C_acute;
408     _8to7map[C_a_circumflex][0] = C_a;
409     _8to7map[C_a_circumflex][1] = C_circumflex;
410     _8to7map[C_a_tilde][0] = C_a;
411     _8to7map[C_a_tilde][1] = C_tilde;
412     _8to7map[C_o_horn_tilde][0] = C_o;
413     _8to7map[C_o_horn_tilde][1] = C_horn;
414     _8to7map[C_o_horn_tilde][2] = C_tilde;
415     _8to7map[C_o_horn_dot_below][0] = C_o;
416     _8to7map[C_o_horn_dot_below][1] = C_horn;
417     _8to7map[C_o_horn_dot_below][2] = C_dot_below;
418     _8to7map[C_u_hook_above][0] = C_u;
419     _8to7map[C_u_hook_above][1] = C_hook_above;
420     _8to7map[C_u_tilde][0] = C_u;
421     _8to7map[C_u_tilde][1] = C_tilde;
422     _8to7map[C_e_grave][0] = C_e;
423     _8to7map[C_e_grave][1] = C_grave;
424     _8to7map[C_e_acute][0] = C_e;
425     _8to7map[C_e_acute][1] = C_acute;
426     _8to7map[C_e_circumflex][0] = C_e;
427     _8to7map[C_e_circumflex][1] = C_circumflex;
428     _8to7map[C_u_dot_below][0] = C_u;
429     _8to7map[C_u_dot_below][1] = C_dot_below;
430     _8to7map[C_i_grave][0] = C_i;
431     _8to7map[C_i_grave][1] = C_grave;
432     _8to7map[C_i_acute][0] = C_i;
433     _8to7map[C_i_acute][1] = C_acute;
434     _8to7map[C_u_horn][0] = C_u;
435     _8to7map[C_u_horn][1] = C_horn;
436     _8to7map[C_u_horn_acute][0] = C_u;
437     _8to7map[C_u_horn_acute][1] = C_horn;
438     _8to7map[C_u_horn_acute][2] = C_acute;
439     _8to7map[C_d_bar][0] = C_d;
440     _8to7map[C_d_bar][1] = C_d;
441     _8to7map[C_u_horn_grave][0] = C_u;
442     _8to7map[C_u_horn_grave][1] = C_horn;
443     _8to7map[C_u_horn_grave][2] = C_grave;
444     _8to7map[C_o_grave][0] = C_o;
445     _8to7map[C_o_grave][1] = C_grave;
446     _8to7map[C_o_acute][0] = C_o;
447     _8to7map[C_o_acute][1] = C_acute;
448     _8to7map[C_o_circumflex][0] = C_o;
449     _8to7map[C_o_circumflex][1] = C_circumflex;
450     _8to7map[C_o_tilde][0] = C_o;
451     _8to7map[C_o_tilde][1] = C_tilde;
452     _8to7map[C_u_horn_hook_above][0] = C_u;
453     _8to7map[C_u_horn_hook_above][1] = C_horn;
454     _8to7map[C_u_horn_hook_above][2] = C_hook_above;
455     _8to7map[C_u_horn_tilde][0] = C_u;
456     _8to7map[C_u_horn_tilde][1] = C_horn;
457     _8to7map[C_u_horn_tilde][2] = C_tilde;
458     _8to7map[C_u_horn_dot_below][0] = C_u;
459     _8to7map[C_u_horn_dot_below][1] = C_horn;
460     _8to7map[C_u_horn_dot_below][2] = C_dot_below;
461     _8to7map[C_u_grave][0] = C_u;
462     _8to7map[C_u_grave][1] = C_grave;
463     _8to7map[C_u_acute][0] = C_u;
464     _8to7map[C_u_acute][1] = C_acute;
465     _8to7map[C_y_grave][0] = C_y;
466     _8to7map[C_y_grave][1] = C_grave;
467     _8to7map[C_a_breve_hook_above][0] = C_a;
468     _8to7map[C_a_breve_hook_above][1] = C_breve;
469     _8to7map[C_a_breve_hook_above][2] = C_hook_above;
470     _8to7map[C_y_acute][0] = C_y;
471     _8to7map[C_y_acute][0] = C_y;
472     _8to7map[C_y_acute][1] = C_acute;
473     _8to7map[C_a_breve_tilde][0] = C_a;
474     _8to7map[C_a_breve_tilde][1] = C_breve;
475     _8to7map[C_a_breve_tilde][2] = C_tilde;
476     _8to7map[C_a_circumflex_tilde][0] = C_a;
477     _8to7map[C_a_circumflex_tilde][1] = C_circumflex;
478     _8to7map[C_a_circumflex_tilde][2] = C_tilde;
479 }
480 
481 
482 /*
483  * vk_8to7_vietnamese: Vietnamese vk_8to7().  See comments for vk_8to7().
484  *		       Generates an "esc" for the following:
485  *			- the esc itself
486  *			- between two d's (upper- or lower-case)
487  *			- between a vowel and a diacritic
488  */
489 static int
vk_8to7_vietnamese(inbuf,outbuf,esc)490 vk_8to7_vietnamese(inbuf, outbuf, esc)
491     u_char	*inbuf;
492     u_char	*outbuf;
493     u_char	esc;
494 {
495     register u_char	c;
496     register u_char	prevc;
497     register u_char	*i, *o, *s;
498 
499     prevc = '\0';
500     i = inbuf;
501     o = outbuf;
502 
503     /* Try to arrange the tests from fastest to slowest */
504     while (c = *i++) {
505 	if ( (c == esc) ||
506 	     (tolower(c) == 'd' && tolower(prevc) == 'd') ||
507 	     (ismodifier(c) && isvowel(prevc) && !ismodified(prevc)) ||
508 	     (isaccent(c) && isvowel(prevc) && !isaccented(prevc))) {
509 	    *o++ = esc;
510 	    *o++ = c;
511 	} else {
512 	    s = _8to7map[c];
513 	    while (*o = *s++) o++;
514 	}
515 	prevc = c;
516     }
517 
518     *o = '\0';
519     return((int) (o - outbuf));
520 }
521 
522 
523 /*
524  * vk_8to7_english: English vk_8to7().	See comments for vk_8to7().
525  *		    Generates an esc for the following:
526  *			- the esc itself
527  *			- an accented/modified vowel
528  *			- the Vietnamese letter d-bar
529  */
530 static int
vk_8to7_english(inbuf,outbuf,esc)531 vk_8to7_english(inbuf, outbuf, esc)
532     u_char	*inbuf;
533     u_char	*outbuf;
534     u_char	esc;
535 {
536     register u_char	c;
537     register u_char	prevc;
538     register u_char	*i, *o, *s;
539 
540     prevc = '\0';
541     i = inbuf;
542     o = outbuf;
543 
544     /* Try to arrange the tests from fastest to slowest */
545     while (c = *i++) {
546 	if ( (c == esc) || isdiacriticized(c) || (tolower(c) == C_d_bar) ) {
547 	    *o++ = esc;
548 	}
549 	s = _8to7map[c];
550 	while (*o = *s++) o++;
551 	prevc = c;
552     }
553 
554     *o = '\0';
555     return((int) (o - outbuf));
556 }
557 
558 
559 /*
560  * vk_8to7: converts the 8-bit Vietnamese "inbuf" into 7-bit
561  *	    vnkeys-compliant data, and stores the result in
562  *	    "outbuf".  The escape character is passed in through "esc".
563  *	    The bias (Vietnamese or English) is specified with "state".
564  *	    Both inbuf and outbuf must be allocated and supplied
565  *	    by the caller.  Inbuf is assumed to be null-terminated.
566  *
567  *	    Returns the size of the actual outbuf data, in bytes,
568  *	    not including the terminating NULL.
569  *	    The returning outbuf is null-terminated.
570  *
571  *	    Note that vk_8to7() does NOT generate a leading
572  *	    \V or \M in the returned outbuf.
573  *
574  *	    The conversion to LITERAL is NOT supported because it
575  *	    won't see too much use.
576  */
vk_8toqr(inbuf,outbuf,esc,state)577 int  FAR PASCAL vk_8toqr(inbuf, outbuf, esc, state)
578 u_char FAR *inbuf;
579 u_char FAR *outbuf;
580 u_char esc;
581 Vk_State state;
582 {
583     static int	inited = 0;
584 
585     if (!inited) {
586         _doinit();	/* private initialization function */
587 	inited = 1;
588     }
589 
590     switch(state) {
591     case VK_ST_ENGLISH:
592 	return vk_8to7_english(inbuf, outbuf, esc);
593     case VK_ST_VIETNAMESE:
594 	return vk_8to7_vietnamese(inbuf, outbuf, esc);
595     default:
596 	return 0;
597     }
598 }
599 
600 
601 
602 
603 /*
604  * vk_init: Initialize the state machine in the given state "st",
605  *  	    using "com" as the
606  * 	    compose key, and "bs" as the backspace character to be
607  * 	    sent out when needed in immediate echo mode.
608  *
609  *	    Returns ID of FSM if successful, -1 if failed.
610  */
vk_init(st,com,bs)611 Vk_Fsm FAR PASCAL vk_init(st, com, bs)
612 Vk_State st;
613 u_char com;
614 u_char bs;
615 
616 {
617     Vk_Fsm	id;
618 
619     for (id = 0; id < VK_MAX_FSMS; id++) {
620     	if (!Fsm_in_use[id]) break;
621     }
622 
623     if (id == VK_MAX_FSMS) return(-1);
624     Fsm_in_use[id] = 1;
625     State[id] = st;
626     Com[id] = com;
627     Bs[id] = bs;
628     Batch[id] = 0; /* by default it's interactive */
629     Prev_temp[id] = 0; /* in case it's initialized mid-stream */
630 
631     vncompose_init((Co_Data FAR *)&Co_data[id]); /* initialize the composition tables */
632 
633     return(id);
634 }
635 
636 
637 /*
638  * vk_step: Takes one input key "inkey" and operates the state machine
639  * 	    accordingly.  The output, if any, is stored in the user-provided
640  * 	    array "outchars", with the number of characters output in
641  *	    "outcount".
642  *
643  */
vk_step(id,inkey,outchars,outcount)644 Vk_State FAR PASCAL vk_step(id, inkey, outchars, outcount)
645 Vk_Fsm id;
646 u_char inkey;
647 u_char FAR outchars[];
648 int FAR *outcount;
649 {
650     u_char		temp;		/* for storate of composed character */
651     int			fl_compose;	/* flag: in compose sequence */
652     int			fl_erase;	/* flag: erase previous vowel */
653 
654 
655     *outcount = 0;
656     while (1) {
657 
658 	switch(State[id]) {
659 
660 /***********************************************/
661 
662 	case VK_ST_LITERAL:
663 	    if (inkey == Com[id]) {
664 		State[id] = VK_ST_ESC_LITERAL;
665 	    } else {
666 		output_ch(inkey, outchars, outcount);
667 	    }
668 	    return(State[id]);
669 
670 /***********************************************/
671 
672 	case VK_ST_ESC_LITERAL:
673 	    switch(inkey) {
674 	    case VK_ESC_VIETNAMESE_1:
675 	    case VK_ESC_VIETNAMESE_2:
676 		State[id] = VK_ST_VIETNAMESE;
677 		break;
678 	    case VK_ESC_ENGLISH_1:
679 	    case VK_ESC_ENGLISH_2:
680 		State[id] = VK_ST_ENGLISH;
681 		break;
682 	    case VK_ESC_LITERAL_1:
683 	    case VK_ESC_LITERAL_2:
684 		State[id] = VK_ST_LITERAL;
685 		break;
686 	    default:
687 		State[id] = VK_ST_LITERAL;
688 		output_ch(Com[id], outchars, outcount);
689 		output_ch(inkey, outchars, outcount);
690 		break;
691 	    }
692 	    return(State[id]);
693 
694 /***********************************************/
695 
696 	case VK_ST_VIETNAMESE:
697 	    if (inkey == Com[id]) {
698 		Prev_State[id] = VK_ST_VIETNAMESE;
699 		State[id] = VK_ST_ESC_VIETMY;
700 	    } else {
701 		temp = vncompose(&Co_data[id], inkey, (int FAR *) &fl_compose, (int FAR *) &fl_erase);
702 		if (Batch[id] && fl_compose) { /* batch mode composition */
703 		    /* give it to EXPLICIT COMPOSITION, which delays the echo */
704 		    Prev_State[id] = VK_ST_VIETNAMESE;
705 		    State[id] = VK_ST_EXPLICIT_COMPOSE;
706 		    Prev_temp[id] = temp; /* save result since we're in delayed echo */
707 		} else { /* interactive mode composition */
708 		    if (fl_erase) {
709 			output_ch(Bs[id], outchars, outcount);
710 		    }
711 		    output_ch(temp, outchars, outcount);
712 		}
713 	    }
714 	    return(State[id]);
715 
716 /***********************************************/
717 
718 	case VK_ST_ENGLISH:
719 	    if (inkey == Com[id]) {
720 		Prev_State[id] = VK_ST_ENGLISH;
721 		State[id] = VK_ST_ESC_VIETMY;
722 	    } else {
723 		output_ch(inkey, outchars, outcount);
724 	    }
725 	    return(State[id]);
726 
727 /***********************************************/
728 
729 	case VK_ST_ESC_VIETMY:
730 	    switch(inkey) {
731 	    case VK_ESC_VIETNAMESE_1:
732 	    case VK_ESC_VIETNAMESE_2:
733 		State[id] = VK_ST_VIETNAMESE;
734 		return(State[id]);
735 	    case VK_ESC_ENGLISH_1:
736 	    case VK_ESC_ENGLISH_2:
737 		State[id] = VK_ST_ENGLISH;
738 		return(State[id]);
739 	    case VK_ESC_LITERAL_1:
740 	    case VK_ESC_LITERAL_2:
741 		State[id] = VK_ST_LITERAL;
742 		return(State[id]);
743 	    default:
744 		/* we got <COM>x, so flush the compose machine first */
745 		Prev_temp[id] = 0;
746 		(void) vncompose(&Co_data[id], (u_char) 0, (int FAR *) &fl_compose, (int FAR *) &fl_erase);
747 
748 		if (inkey == Com[id]) {
749 		    output_ch(Com[id], outchars, outcount);
750 		    State[id] = Prev_State[id];
751 		    return(State[id]);
752 		} else {
753 		    State[id] = VK_ST_EXPLICIT_COMPOSE;
754 		    break; /* we DON'T return, go back to start composing on this key */
755 		}
756 	    }
757 	    break;
758 
759 /***********************************************/
760 
761 	case VK_ST_EXPLICIT_COMPOSE:
762 	    temp = vncompose(&Co_data[id], inkey, (int FAR *) &fl_compose, (int FAR *) &fl_erase);
763 	    if (fl_compose) { /* composition sequence starting or continuing */
764 		if (!fl_erase && Prev_temp[id]) {
765 		    /* we just ended a composition sequence, e.g., \ae */
766 		    output_ch(Prev_temp[id], outchars, outcount);
767 		    if (!Batch[id] && Prev_State[id] == VK_ST_VIETNAMESE) {
768 			/* we're not really in delayed echo */
769 			output_ch(temp, outchars, outcount);
770 			State[id] = VK_ST_VIETNAMESE;
771 		    } else {
772 			Prev_temp[id] = temp; /* save result since we're in delayed echo */
773 		    }
774 		} else { /* did not just end a composition sequence */
775 		    Prev_temp[id] = temp; /* save result since we're in delayed echo */
776 		}
777 	    } else { /* composition is finished */
778 		State[id] = Prev_State[id];
779 
780 		/* Now, why was composition finished? */
781 		if (fl_erase) { /* because it's completed, e.g., \e^' */
782 		    output_ch(temp, outchars, outcount);
783 		} else if (temp == Com[id]) { /* because it's ended by \, e.g., \e^\ */
784 		    output_ch(Prev_temp[id], outchars, outcount);
785 		    State[id] = VK_ST_ESC_VIETMY;
786 		} else { /* because it's ended by something else, e.g., \m or \e^m */
787 		    if (Prev_temp[id] != 0) {
788 			output_ch(Prev_temp[id], outchars, outcount);
789 		    }
790 		    output_ch(temp, outchars, outcount);
791 		}
792 	    }
793 	    return(State[id]);
794 	} /* switch(St[id]) */
795     } /* forever */
796 }
797 
798 
799 /*
800  * vk_get: called when the user wishes to query the internal
801  *	   state of the FSM.
802  */
vk_get(id,value,get_flag)803 void FAR PASCAL vk_get(id, value, get_flag)
804 Vk_Fsm id;
805 u_int FAR *value;
806 int get_flag;
807 {
808     if (get_flag & VK_GET_STATE) {
809 	*((Vk_State FAR *) value) = State[id];
810     } else if (get_flag & VK_GET_ESC) {
811 	*((u_char FAR *) value) = Com[id];
812     } else if (get_flag & VK_GET_BS) {
813 	*((u_char FAR *) value) = Bs[id];
814     } else if (get_flag & VK_GET_BATCH) {
815 	*((u_char FAR *) value) = Batch[id];
816     }
817 }
818 
819 
820 /*
821  * vk_set: called when the user wishes to set the internal
822  *	   state of the FSM.
823  */
vk_set(id,value,set_flag)824 void FAR PASCAL vk_set(id, value, set_flag)
825 Vk_Fsm id;
826 u_int value;
827 int set_flag;
828 {
829     if (set_flag & VK_SET_STATE) {
830 	State[id] = (Vk_State) value;
831 	vk_flush(id, 0, 0); /* flush the FSM whenever we set the state */
832     } else if (set_flag & VK_SET_ESC) {
833 	Com[id] = (u_char) value;
834     } else if (set_flag & VK_SET_BS) {
835 	Bs[id] = (u_char) value;
836     } else if (set_flag & VK_SET_BATCH) {
837 	Batch[id] = (u_char) value;
838     }
839 }
840 
841 
842 /*
843  * vk_flush: flushes the characters that are still pending
844  *	     in the FSM.  If "outchars" is non-zero, the pending
845  *	     characters are stored there.
846  */
vk_flush(id,outchars,outcount)847 void FAR PASCAL vk_flush(id, outchars, outcount)
848 Vk_Fsm id;
849 u_char FAR *outchars;
850 int FAR *outcount;
851 {
852     char	dumbuf[3];
853     int		dumcount;
854 
855     /* do two com's and throw away the com itself */
856     if (outchars) {
857 	vk_step(id, Com[id], outchars, outcount);
858     } else {
859 	vk_step(id, Com[id], (u_char FAR *)dumbuf, (int FAR *)&dumcount);
860     }
861     vk_step(id, Com[id], (u_char FAR *)dumbuf, (int FAR *) &dumcount);
862 }
863 
864 
865 /*
866  * vk_end:   vk_flush() the characters that are still pending
867  *	     in the FSM, and frees up the FSM for another call.
868  */
vk_end(id,outchars,outcount)869 void FAR PASCAL vk_end(id, outchars, outcount)
870 Vk_Fsm id;
871 u_char FAR *outchars;
872 int FAR *outcount;
873 {
874     vk_flush(id, outchars, outcount);
875     Fsm_in_use[id] = 0; /* free up the FSM */
876 }
877 
878 
879 /*
880  * Vncompos.c is an implementation of the efficient and flexible
881  * composition algorithm due to Dr. Hoc Ngo of the Viet-Std group.
882  */
883 
vncompose(Co_data,inchar,fl_compose,fl_erase)884 u_char FAR PASCAL vncompose(Co_data, inchar, fl_compose, fl_erase)
885 Co_Data FAR *Co_data;
886 u_char inchar;
887 int FAR *fl_compose;
888 int FAR *fl_erase;
889 {
890     u_char	tonemark;
891 
892 
893     while (1) {
894 	switch(C_state) {
895 
896 /***************************************/
897 	case CO_ST_LEVEL1:
898 	    C1 = inchar;
899 	    I1 = icode[C1];
900 	    if (I1 == 0 || I1 > 28) { /* won't compose w/ anything, e.g., "n" */
901 		*fl_compose = 0;	/* not composing */
902 	    } else { /* C1 might compose, e.g., "e" */
903 		*fl_compose = 1;
904 		C_state = CO_ST_LEVEL2;
905 	    }
906 	    *fl_erase = 0; /* no erase */
907 	    return(C1);
908 
909 
910 /***************************************/
911 	case CO_ST_LEVEL2:
912 	    C2 = inchar;
913 	    I2 = icode[C2];
914 	    if ((RHcode[I1] & LHcode[I2]) == 0) { /* C1 & C2 won't combine, e.g., en */
915 		C_state = CO_ST_LEVEL1; /* go back to level 1 and process */
916 		break;
917 	    }
918 	    /* C1 & C2 do combine, e.g., e^ or e' */
919 	    I1 = I1 + offset[I2];
920 	    if (LHcode[I2] & 0x38) { /* C2 is a modifier, e.g., e^ */
921 		C_state = CO_ST_LEVEL3;
922 		*fl_compose = 1;
923 	    } else { /* C2 is a tone mark, e.g., e' */
924 		*fl_compose = 0;
925 		C_state = CO_ST_LEVEL1;
926 	    }
927 
928 	    tonemark = LHcode[I2] & (u_char) 0x07;
929 	    *fl_erase = 1;
930 	    return(table[I1][tonemark]);
931 
932 /***************************************/
933 	case CO_ST_LEVEL3:
934 	    C_state = CO_ST_LEVEL1;
935 	    C3 = inchar;
936 	    I3 = icode[C3];
937 	    tonemark = LHcode[I3] & (u_char) 0x07;
938 	    if (tonemark == 0) { /* C3 is not a tone mark, e.g., e^n */
939 		break;
940 	    }
941 	    /* C3 is a tone mark, e.g., e^' */
942 	    *fl_compose = 0;
943 	    *fl_erase = 1;
944 	    return(table[I1][tonemark]);
945 	}
946     } /* forever */
947 }
948 
949 
vncompose_init(Co_data)950 void FAR PASCAL vncompose_init(Co_data)
951 Co_Data FAR *Co_data;
952 {
953     int	n;
954     u_char *ptr1, *ptr2;
955 
956     C_state = CO_ST_LEVEL1;
957 
958     /*********** icode **********/
959     for (n = sizeof(icode) - 1; n >= 0; n--) {
960 	orig_icode[n] = 0;
961     }
962 
963     orig_icode[C_D]			=  1;
964     orig_icode[C_A]			=  2;
965     orig_icode[C_A_breve]		=  3;
966     orig_icode[C_A_circumflex]	=  4;
967 
968     orig_icode[C_E]			=  6;
969     orig_icode[C_I]			=  7;
970     orig_icode[C_E_circumflex]	=  8;
971     orig_icode[C_O]			=  9;
972     orig_icode[C_U]			= 10;
973     orig_icode[C_O_circumflex]	= 11;
974     orig_icode[C_O_horn]		= 12;
975     orig_icode[C_U_horn]		= 13;
976     orig_icode[C_Y]			= 14;
977 
978 
979     orig_icode[C_d]			= 15;
980     orig_icode[C_a]			= 16;
981     orig_icode[C_a_breve]		= 17;
982     orig_icode[C_a_circumflex]	= 18;
983 
984     orig_icode[C_e]			= 20;
985     orig_icode[C_i]			= 21;
986     orig_icode[C_e_circumflex]	= 22;
987     orig_icode[C_o]			= 23;
988     orig_icode[C_u]			= 24;
989     orig_icode[C_o_circumflex]	= 25;
990     orig_icode[C_o_horn]		= 26;
991     orig_icode[C_u_horn]		= 27;
992     orig_icode[C_y]			= 28;
993 
994     orig_icode[CO_ACUTE]		= 29;
995     orig_icode[CO_GRAVE]		= 30;
996     orig_icode[CO_HOOK_ABOVE]	= 31;
997     orig_icode[CO_TILDE]		= 32;
998     orig_icode[CO_DOT_BELOW]		= 33;
999 
1000     orig_icode[CO_BREVE]		= 34;
1001     orig_icode[CO_CIRCUMFLEX]	= 35;
1002     orig_icode[CO_HORN]		= 36;
1003 
1004     for (n = sizeof(icode) - 1; n >= 0; n--) {
1005 	icode[n] = orig_icode[n];
1006     }
1007 
1008     /*********** characters used for diacritics **********/
1009     Co_data->acute = CO_ACUTE;
1010     Co_data->grave = CO_GRAVE;
1011     Co_data->hook_above = CO_HOOK_ABOVE;
1012     Co_data->tilde = CO_TILDE;
1013     Co_data->dot_below = CO_DOT_BELOW;
1014     Co_data->breve = CO_BREVE;
1015     Co_data->circumflex = CO_CIRCUMFLEX;
1016     Co_data->horn = CO_HORN;
1017 }
1018 
1019 
1020 /*
1021  * vncompose_set() allows a character to be specified for a particular
1022  * diacritic.  The caller must pass in the Co_data composition structure.
1023  * It operates by swapping the icode[] index of the characters.
1024  * If successful, it returns 1.  Else zero.
1025  *
1026  */
1027 
vncompose_set(diacritic,newchar,Co_data)1028 int FAR PASCAL vncompose_set(diacritic, newchar, Co_data)
1029 int diacritic;
1030 u_char newchar;
1031 Co_Data FAR *Co_data;
1032 {
1033     u_char	currentchar;
1034     u_char FAR	*ptr;
1035 
1036     switch(diacritic) {
1037     case CO_BREVE:
1038 	currentchar = Co_data->breve;
1039 	ptr = (u_char FAR *) &(Co_data->breve);
1040 	break;
1041     case CO_CIRCUMFLEX:
1042 	currentchar = Co_data->circumflex;
1043 	ptr = (u_char FAR *) &(Co_data->circumflex);
1044 	break;
1045     case CO_HORN:
1046 	currentchar = Co_data->horn;
1047 	ptr = (u_char FAR *) &(Co_data->horn);
1048 	break;
1049     case CO_ACUTE:
1050 	currentchar = Co_data->acute;
1051 	ptr = (u_char FAR *) &(Co_data->acute);
1052 	break;
1053     case CO_GRAVE:
1054 	currentchar = Co_data->grave;
1055 	ptr = (u_char FAR *) &(Co_data->grave);
1056 	break;
1057     case CO_HOOK_ABOVE:
1058 	currentchar = Co_data->hook_above;
1059 	ptr = (u_char FAR *) &(Co_data->hook_above);
1060 	break;
1061     case CO_TILDE:
1062 	currentchar = Co_data->tilde;
1063 	ptr = (u_char FAR *) &(Co_data->tilde);
1064 	break;
1065     case CO_DOT_BELOW:
1066 	currentchar = Co_data->dot_below;
1067 	ptr = (u_char FAR *) &(Co_data->dot_below);
1068 	break;
1069     default:
1070 	return 0;
1071     }
1072 
1073     if (newchar != currentchar) {
1074         icode[newchar] = icode[currentchar];
1075         icode[currentchar] = orig_icode[currentchar];
1076         *ptr = newchar;
1077     }
1078     return(1);
1079 } /* vncompose_set */
1080