*** empty log message ***
[m17n/m17n-test.git] / imtest.c
1 #include <stdio.h>
2 #include <string.h>
3
4 #include <m17n.h>
5 #include <m17n-misc.h>
6
7 MSymbol utf8;
8
9 void
10 show_description (MText *mt, int indent)
11 {
12   if (mt)
13     {
14       printf ("\n%*sdescription: ", indent, "");
15       mconv_encode_stream (utf8, mt, stdout);
16     }
17   else
18     printf ("\n%*sno-description", indent, "");
19 }
20
21 void
22 show_input_method (MSymbol lang, MSymbol name, int indent)
23 {
24   MText *mt;
25   MSymbol language;
26
27   if (lang == Mt)
28     language = msymbol ("generic");
29   else if ((language = msymbol_get (lang, Mlanguage)) == Mnil)
30     language = lang;
31   printf ("\n%*slanguage: %s name: %s",
32           indent, "", msymbol_name (language), msymbol_name (name));
33   mt = minput_get_description (lang, name);
34   show_description (mt, indent + 2);
35   if (mt)
36     m17n_object_unref (mt);
37 }
38
39 void
40 show_command (MSymbol cmd, MPlist *p, int indent)
41 {
42   printf ("\n%*sname: %s", indent, "", msymbol_name (cmd));
43   indent += 2;
44   show_description (mplist_value (p), indent);
45   p = mplist_next (p);
46   if (mplist_key (p) == Mnil)
47     printf ("\n%*skey-sequence: global assignments are effective", indent, "");
48   else
49     for (; mplist_key (p) != Mnil; p = mplist_next (p))
50       if (mplist_key (p) == Mplist)
51         {
52           MPlist *p0 = mplist_value (p);
53
54           if (mplist_key (p0) != Mnil)
55             {
56               printf ("\n%*skey-sequence:", indent, "");
57               for (; mplist_key (p0) != Mnil; p0 = mplist_next (p0))
58                 printf (" %s", msymbol_name ((MSymbol) mplist_value (p0)));
59             }
60         }
61 }
62
63 void
64 show_variable (MSymbol var, MPlist *p, int indent)
65 {
66   MSymbol type;
67
68   printf ("\n%*sname: %s", indent, "", msymbol_name (var));
69   indent += 2;
70   show_description (mplist_value (p), indent);
71   p = mplist_next (p);
72   printf ("\n%*sinitial-value: ", indent, "");
73   type = mplist_key (p);
74   if (type == Minteger)
75     printf ("%d", (int) mplist_value (p));
76   else if (type == Msymbol)
77     printf ("%s", msymbol_name ((MSymbol) mplist_value (p)));
78   else                          /*  type == Mtext */
79     {
80       printf ("\"");
81       mconv_encode_stream (utf8, (MText *) mplist_value (p), stdout);
82       printf ("\"");
83     }
84   p = mplist_next (p);
85   printf ("\n%*svalid-value:", indent, "");
86   if (mplist_key (p) == Mnil)
87     printf (" any value of type %s", msymbol_name (type));
88   else
89     for (; mplist_key (p) != Mnil; p = mplist_next (p))
90       {
91         MSymbol this_type = mplist_key (p);
92
93         if (type != this_type && (type != Minteger || this_type != Mplist))
94           /* This shouldn't happen.  */
95           continue;
96         if (this_type == Minteger)
97           printf (" %d", (int) mplist_value (p));
98         else if (this_type == Msymbol)
99           printf (" %s", msymbol_name ((MSymbol) mplist_value (p)));
100         else if (this_type == Mtext)
101           {
102             printf (" \"");
103             mconv_encode_stream (utf8, (MText *) mplist_value (p), stdout);
104             printf ("\"");
105           }
106         else                    /* type == Mplist */
107           {
108             MPlist *p0 = mplist_value (p);
109
110             printf (" %d", (int) mplist_value (p0));
111             p0 = mplist_next (p0);
112             printf ("-%d", (int) mplist_value (p0));
113           }
114       }
115 }
116
117 #if 0
118 MPlist *im_list = NULL;
119
120 MInputMethod *
121 get_im (MSymbol lang, MSymbol name)
122 {
123   MInputMethod *im;
124   MPlist *p;
125
126   if (! im_list)
127     im_list = mplist ();
128   for (p = im_list; mplist_key (p) != Mnil; p = mplist_next (p))
129     {
130       im = mplist_value (p);
131       if (im->language == lang && im->name == name)
132         return im;
133     }
134   im = minput_open_im (lang, name, NULL);
135   if (! im)
136     return NULL;
137   mplist_push (im_list, Mt, im);
138   return im;
139 }
140
141 void
142 close_ims ()
143 {
144   MInputMethod *im;
145   MPlist *p;
146
147   if (! im_list)
148     return;
149   for (p = im_list; mplist_key (p) != Mnil; p = mplist_next (p))
150     {
151       im = mplist_value (p);
152       minput_close_im (im);
153     }
154   m17n_object_unref (im_list);
155 }
156
157 void
158 show_preedit (MInputContext *ic)
159 {
160   int len = mtext_len (ic->preedit);
161   int i;
162
163   printf ("preedit:");
164   for (i = 0; i < len; i++)
165     printf (" U+%04X", mtext_ref_char (ic->preedit, i));
166   printf ("\n");
167   fflush (stdout);
168 }
169
170 void
171 show_candidates (MInputContext *ic)
172 {
173   MPlist *plist = ic->candidate_list;
174   int idx = ic->candidate_index;
175   int items;
176   int i, j, len;
177   MText *mt;
178   
179   printf ("candidates:");
180   while (1)
181     {
182       if (mplist_key (plist) == Mtext)
183         items = mtext_len ((MText *) mplist_value (plist));
184       else
185         items = mplist_length ((MPlist *) mplist_value (plist));
186       if (idx < items)
187         break;
188       idx -= items;
189       plist = mplist_next (plist);
190     }
191   if (mplist_key (plist) == Mtext)
192     {
193       mt = (MText *) mplist_value (plist);
194       for (i = 0; i < items; i++)
195         {
196           if (i == idx)
197             printf ("[U+%04X]", mtext_ref_char (mt, i));
198           else
199             printf (" U+%04X ", mtext_ref_char (mt, i));
200         }
201     }
202   else
203     {
204       plist = (MPlist *) mplist_value (plist);
205       for (i = 0; i < items; i++, plist = mplist_next (plist))
206         {
207           mt = (MText *) mplist_value (plist);
208           len = mtext_len (mt);
209           if (i == idx)
210             printf ("[");
211           else
212             printf (" ");
213           for (j = 0; j < len; j++)
214             {
215               if (j > 0)
216                 printf (",");
217               printf ("U+%04X", mtext_ref_char (mt, j));
218             }
219           if (i == idx)
220             printf ("[");
221           else
222             printf (" ");
223         }
224     }
225   printf ("\n");
226   fflush (stdout);
227 }
228
229 void
230 show_produced (MText *mt)
231 {
232   int len = mtext_len (mt);
233   int i;
234
235   printf ("produced:");
236   for (i = 0; i < len; i++)
237     printf (" U+%04X", mtext_ref_char (mt, i));
238   printf ("\n");
239   fflush (stdout);
240 }
241
242 int
243 main (int argc, char **argv)
244 {
245   char line[256];
246   MSymbol lang, name;
247   MInputMethod *im = NULL;
248   MInputContext *ic = NULL;
249
250   M17N_INIT ();
251
252   while (fgets (line, 256, stdin))
253     {
254       if (strncmp (line, "open", 4) == 0)
255         {
256           char langstr[16], namestr[16];
257
258           if (ic)
259             minput_destroy_ic (ic);
260           if (sscanf (line + 4, "%s %s", langstr, namestr) != 2)
261             continue;
262           lang = msymbol (langstr);
263           name = msymbol (namestr);
264           printf ("opening im \"%s\" \"%s\" ...", langstr, namestr);
265           im = get_im (lang, name);
266           if (! im)
267             {
268               printf (" failed\n");
269               fflush (stdout);
270               continue;
271             }
272           printf (" done\n");
273           printf ("creating context ...");
274           ic = minput_create_ic (im, NULL);
275           if (! ic)
276             {
277               printf ("failed\n");
278               fflush (stdout);
279               minput_close_im (im);
280               im = NULL;
281               continue;
282             }
283           printf (" done\n");
284           fflush (stdout);
285         }
286       else if (! ic)
287         {
288           printf ("no input method is available\n");
289           fflush (stdout);
290           continue;
291         }
292       else
293         {
294           int i;
295           char keystr[4];
296           MSymbol key;
297
298           for (i = 0; line[i] != '\n'; i++)
299             {
300               int c = line[i];
301               int result;
302               MText *mt;
303
304               if (c < 32)
305                 sprintf (keystr, "C-%c", c + 64);
306               else
307                 sprintf (keystr, "%c", c);
308               key = msymbol (keystr);
309               result = minput_filter (ic, key, NULL);
310               if (ic->preedit_changed)
311                 show_preedit (ic);
312               if (ic->candidates_changed && ic->candidate_show
313                   && ic->candidate_list)
314                 show_candidates (ic);
315               if (result > 0)
316                 continue;
317               mt = mtext ();
318               minput_lookup (ic, key, NULL, mt);
319               show_produced (mt);
320               m17n_object_unref (mt);
321             }
322         }
323     }
324
325   if (ic)
326     minput_destroy_ic (ic);
327   close_ims ();
328   M17N_FINI ();
329   exit (0);
330 }
331
332 #else
333 int
334 main (int argc, char **argv)
335 {
336   MPlist *plist, *pl;
337   MSymbol unicode, test, commit;
338   MPlist *keyseq;
339   int test_input_method_found = 0;
340
341   /* To make database module find test.mim in this directory.  */
342   mdatabase_dir = ".";
343
344   M17N_INIT ();
345   utf8 = msymbol ("utf-8");
346   unicode = msymbol ("unicode");
347   test = msymbol ("test");
348   commit = msymbol ("commit");
349
350   mdatabase_define (msymbol ("input"), msymbol ("command"), Mnil, Mnil,
351                     NULL, "im-cmd.tbl");
352   printf ("List all available input methods:");
353   plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
354   if (! plist)
355     goto err;
356   for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
357     {
358       MDatabase *mdb = mplist_value (pl);
359       MSymbol *tag = mdatabase_tag (mdb);
360
361       show_input_method (tag[1], tag[2], 2);
362       if (tag[1] == Mt && tag[2] == test)
363         test_input_method_found = 1;
364     }
365   printf ("\n");
366   m17n_object_unref (plist);
367   
368   printf ("Is test input method found?\n");
369   if (! test_input_method_found)
370     goto err;
371   printf ("  Found\n");
372
373   printf ("Describe commit command and its global key assignment:");
374   plist = minput_get_commands (Mnil, Mnil);
375   if (! plist || ! (plist = mplist_get (plist, commit)))
376     goto err;
377   show_command (commit, plist, 2);
378   printf ("\n");
379
380   /* Assign S-space to the command "commit" globally.  */
381   printf ("Assign S-space to commit globally:");
382   keyseq = mplist ();
383   mplist_add (keyseq, Msymbol, msymbol ("S-space"));
384   if (minput_assign_command_keys (Mnil, Mnil, commit, keyseq) < 0)
385     goto err;
386   /* Check the above assignment.  */
387   plist = minput_get_commands (Mnil, Mnil);
388   plist = mplist_get (plist, commit);
389   show_command (commit, plist, 2);
390   printf ("\n");
391
392   printf ("Describe commit command and its local key assignment in \"test\":");
393   plist = minput_get_commands (Mt, test);
394   if (! plist
395       || ! (plist = mplist_get (plist, commit)))
396     goto err;
397   show_command (commit, plist, 2);
398   printf ("\n");
399
400   printf ("Assign A-space to commit locally in \"test\":");
401   mplist_put (keyseq, Msymbol, msymbol ("A-space"));
402   if (minput_assign_command_keys (Mt, test, commit, keyseq) < 0
403       || ! (plist = minput_get_commands (Mt, test))
404       || ! (plist = mplist_get (plist, commit)))
405     goto err;
406   show_command (commit, plist, 2);
407   printf ("\n");
408
409   printf ("Cancel the above locale assignment:");
410   if (minput_assign_command_keys (Mt, test, commit, NULL) < 0
411       || ! (plist = minput_get_commands (Mt, test))
412       || ! (plist = mplist_get (plist, commit)))
413     goto err;
414   show_command (commit, plist, 2);
415   printf ("\n");
416
417   printf ("Assign A-space in addition to global assignments to commit:");
418   minput_assign_command_keys (Mt, test, commit, keyseq);
419   plist = mplist_next (mplist_get (minput_get_commands (Mnil, Mnil), commit));
420   for (; mplist_key (plist) != Mnil; plist = mplist_next (plist))
421     minput_assign_command_keys (Mt, test, commit, mplist_value (plist));
422
423   if (! (plist = minput_get_commands (Mt, test))
424       || ! (plist = mplist_get (plist, commit)))
425     goto err;
426   show_command (commit, plist, 2);
427   printf ("\n");
428
429   printf ("Cancel the assignment without making global assignment effective:");
430   /* Make KEYSEQ an empty plist.  */
431   mplist_pop (keyseq);
432   minput_assign_command_keys (Mt, test, commit, NULL);
433   minput_assign_command_keys (Mt, test, commit, keyseq);
434   if (! (plist = minput_get_commands (Mt, test))
435       || ! (plist = mplist_get (plist, commit)))
436     goto err;
437   show_command (commit, plist, 2);
438   printf ("\n");
439   m17n_object_unref (keyseq);
440
441   printf ("List variables used in \"test\":");
442   plist = minput_get_variables (Mt, test);
443   if (! plist)
444     goto err;
445   for (; mplist_key (plist) != Mnil;  plist = mplist_next (plist))
446     show_variable (mplist_key (plist), mplist_value (plist), 2);
447   printf ("\n");
448
449   printf ("Set the first variable to hello ... should fail:\n");
450   plist = minput_get_variables (Mt, test);
451   if (minput_set_variable (Mt, test, mplist_key (plist), msymbol ("hello")) < 0)
452     printf ("  Correctly failed\n");
453   else
454     printf ("  Incorrectly succeeded\n");
455
456   printf ("Set the first variable to no ... should succeed:\n");
457   if (minput_set_variable (Mt, test, mplist_key (plist), msymbol ("no")) < 0)
458     printf ("  Incorrectly failed\n");
459   else
460     printf ("  Correctly succeeded\n");
461
462   plist = mplist_next (plist);
463   printf ("Set the second variable to 5 ... should fail:\n");
464   if (minput_set_variable (Mt, test, mplist_key (plist), (void *) 5) < 0)
465     printf ("  Correctly failed\n");
466   else
467     printf ("  Incorrectly succeeded\n");
468   printf ("Set the second variable to 10 ... should succeeded:\n");
469   if (minput_set_variable (Mt, test, mplist_key (plist), (void *) 10) < 0)
470     printf ("  Incorrectly failed\n");
471   else
472     printf ("  Correctly succeeded\n");
473
474   plist = mplist_next (plist);
475   {
476     char *str = "hello";
477     MText *mt = mtext_from_data (str, strlen (str), MTEXT_FORMAT_US_ASCII);
478
479     printf ("Set the third variable to \"hello\" ... should succeed:\n");
480     if (minput_set_variable (Mt, test, mplist_key (plist), mt) < 0)
481       printf ("  Incorrectly failed\n");
482     else
483       printf ("  Correctly succeeded\n");
484     m17n_object_unref (mt);
485   }
486
487   printf ("List variables used in \"test\" again:");
488   plist = minput_get_variables (Mt, test);
489   if (! plist)
490     goto err;
491   for (; mplist_key (plist) != Mnil;  plist = mplist_next (plist))
492     show_variable (mplist_key (plist), mplist_value (plist), 2);
493   printf ("\n");
494
495   M17N_FINI ();
496   exit (0);
497
498  err:
499   printf (" ...failed!\n");
500   exit (1);
501 }
502 #endif
503