*** empty log message ***
[m17n/m17n-test.git] / mim-list.c
1 /* mim-list.c -- List all m17n-lib input methods.  */
2
3 #include <stdio.h>
4 #include <stdarg.h>
5
6 #include <m17n.h>
7 #include <m17n-misc.h>
8
9 /* Frequently used symbols.  */
10 MSymbol Mutf_8;
11 MSymbol Mspace;
12
13 /* Print arguments and exit with 1.  */
14 void
15 fatal (char *fmt, ...)
16 {
17   va_list ap;
18
19   va_start (ap, fmt);
20   vprintf (fmt, ap);
21   va_end (ap);
22   exit (1);
23 }
24
25 /* If the key of PLIST is not TYPE, print error and exit.  */
26 void
27 check_type (MPlist *plist, MSymbol type)
28 {
29   if (mplist_key (plist) != type)
30     fatal ("Type \"%s\" must be \"%s\".\n",
31            msymbol_name (mplist_key (plist)), msymbol_name (type));
32 }
33   
34
35 /* Dump the first line of documentation text MT.   */
36 void
37 dump_doc (MText *mt)
38 {
39   int pos = mtext_chr (mt, '\n');
40
41   if (pos < 0)
42     mconv_encode_stream (Mutf_8, mt, stdout);
43   else
44     {
45       mt = mtext_duplicate (mt, 0, pos);
46       mconv_encode_stream (Mutf_8, mt, stdout);
47       printf (" ...");
48       m17n_object_unref (mt);
49     }
50 }
51
52 /* Dump the title and icon filename stored in the plist TITLE_ICON.  */
53 void
54 dump_title_icon (MPlist *title_icon)
55 {
56   check_type (title_icon, Mtext);
57   mconv_encode_stream (Mutf_8, (MText *) mplist_value (title_icon), stdout);
58   title_icon = mplist_next (title_icon);
59   if (mplist_key (title_icon) == Mtext)
60     {
61       printf ("\n  ICON file: ");
62       mconv_encode_stream (Mutf_8, (MText *) mplist_value (title_icon), stdout);
63     }
64 }
65
66
67 /* Dump the value of plist VAL.  If TYPE is not Mnil, check if it
68    doesn't conflict with VAL.  */
69 void
70 dump_val (MPlist *val, MSymbol type)
71 {
72   MSymbol valtype = mplist_key (val);
73
74   if (type != Mnil)
75     {
76       /* Check if VALTYPE is valid or not.  */
77       if (valtype != type
78           && ! (valtype == Mplist && type == Minteger))
79         fatal ("Value type %s not much with %s\n",
80                msymbol_name (valtype), msymbol_name (type));
81     }
82   if (valtype == Minteger)
83     printf ("%d", (int) mplist_value (val));
84   else if (valtype == Msymbol)
85     printf ("%s", msymbol_name ((MSymbol) mplist_value (val)));
86   else if (valtype == Mtext)
87     mconv_encode_stream (Mutf_8, (MText *) mplist_value (val), stdout);
88   else if (valtype == Mplist)
89     {
90       int from, to;
91
92       val = mplist_value (val);
93       check_type (val, Minteger);
94       from = (int) mplist_value (val);
95       val = mplist_next (val);
96       check_type (val, Minteger);
97       to = (int) mplist_value (val);
98       printf ("%d..%d", from, to);
99     }
100   else
101     fatal ("Invalid type: %s", msymbol_name ((MSymbol) mplist_value (val)));
102 }
103
104 /* Dump the information about the first variable stored in VARIABLES.
105    VARIABLES is a plist of this form:
106      (VARNAME (DOC-MTEXT [ DEFAULT-VALUE [ VALUE ... ] ] ) ...)
107    Returns `cddr' of VARIABLES.
108  */
109
110 MPlist *
111 dump_var (MPlist *variables)
112 {
113   MSymbol name, type;
114   MPlist *plist;
115   MText *mt;
116
117   check_type (variables, Msymbol);
118   name = mplist_value (variables);
119   printf ("\n    %s: ", msymbol_name (name));
120   variables = mplist_next (variables);
121   check_type (variables, Mplist);
122   plist = mplist_value (variables);
123   variables = mplist_next (variables);
124   if (mplist_key (variables) == Mnil)
125     variables = NULL;
126   /* PLIST ::= (DOC-MTEXT [ DEFAULT-VALUE [ VALUE ... ] ] ) */
127   if (mplist_key (plist) == Mnil)
128     {
129       printf ("No docstring.");
130       return variables;
131     }
132   if (mplist_key (plist) == Msymbol
133       && (MSymbol) mplist_value (plist) == Mnil)
134     printf ("No docstring.");
135   else
136     {
137       check_type (plist, Mtext);
138       mt = mplist_value (plist);
139       if (mtext_len (mt) > 0)
140         dump_doc (mt);
141     }
142   plist = mplist_next (plist);
143   if (mplist_key (plist) == Mnil)
144     {
145       printf ("\n      No default value, no restriction.");
146       return variables;
147     }
148   type = mplist_key (plist);
149   printf ("\n      Default value (%s): ", msymbol_name (type));
150   dump_val (plist, Mnil);
151   plist = mplist_next (plist);
152   if (mplist_key (plist) == Mnil)
153     {
154       printf ("\n      No restriction");
155       return variables;
156     }
157   
158   while (mplist_key (plist) != Mnil)
159     {
160       printf ("\n      Valid value: ");
161       dump_val (plist, type);
162       plist = mplist_next (plist);
163     }
164   return variables;
165 }
166
167 /* Dump the information about the first command stored in COMMANDS.
168    COMMANDS is a plist of this form:
169      (CMDNAME (DOC-MTEXT [ KEYSEQ ... ] ) ...)
170    Returns `cddr' of COMMANDS.
171  */
172
173 MPlist *
174 dump_cmd (MPlist *commands)
175 {
176   MSymbol name;
177   MPlist *plist;
178   MText *mt;
179
180   check_type (commands, Msymbol);
181   name = mplist_value (commands);
182   printf ("\n    %s: ", msymbol_name (name));
183   commands = mplist_next (commands);
184   check_type (commands, Mplist);
185   plist = mplist_value (commands);
186   commands = mplist_next (commands);
187   if (mplist_key (commands) == Mnil)
188     commands = NULL;
189   /* PLIST ::= (DOC-MTEXT [ KEYSEQ ... ] ) */
190   if (mplist_key (plist) == Mnil)
191     {
192       printf ("No docstring.");
193       return commands;
194     }
195   check_type (plist, Mtext);
196   mt = mplist_value (plist);
197   if (mtext_len (mt) > 0)
198     dump_doc (mt);
199   plist = mplist_next (plist);
200   if (mplist_key (plist) == Mnil)
201     {
202       printf ("\n      No binding.");
203       return commands;
204     }
205   while (mplist_key (plist) != Mnil)
206     {
207       MPlist *keyseq;
208
209       check_type (plist, Mplist);
210       keyseq = mplist_value (plist);
211       printf ("\n      binding:");
212       while (mplist_key (keyseq) != Mnil)
213         {
214           check_type (keyseq, Msymbol);
215           if ((MSymbol) mplist_value (keyseq) == Mspace)
216             printf (" SPC");
217           else
218             printf (" %s", msymbol_name ((MSymbol) mplist_value (keyseq)));
219           keyseq = mplist_next (keyseq);
220         }
221       plist = mplist_next (plist);
222     }
223   return commands;
224 }
225
226 /* Dump information about all input methods.  It accepts optional one
227    command-line argument LANG.  If LANG is specified, list only input
228    methods for LANG.  */
229
230 int
231 main (int argc, char **argv)
232 {
233   MSymbol lang;
234   MPlist *plist, *pl;
235   int num;
236
237   M17N_INIT ();
238   Mutf_8 = msymbol ("utf-8");
239   Mspace = msymbol (" ");
240
241   if (argc > 1)
242     lang = msymbol (argv[1]);
243   else
244     lang = Mnil;
245
246   plist = mdatabase_list (msymbol ("input-method"), lang, Mnil, Mnil);
247   for (num = 0, pl = plist; pl && mplist_key (pl) != Mnil;
248        num++, pl = mplist_next (pl))
249     {
250       MSymbol *tags = mdatabase_tag (mplist_value (pl));
251       char *lang = tags[1] == Mt ? "generic" : msymbol_name (tags[1]);
252       MPlist *title_icon, *variables, *commands;
253       MText *mt;
254
255       if (tags[2] == Mnil)
256         printf ("\nLanguage:%s Name:%s (for inclusion)",
257                 lang, msymbol_name (tags[3]));
258       else
259         printf ("\nLanguage:%s Name:%s",
260                 lang, msymbol_name (tags[2]));
261       mt = minput_get_description (tags[1], tags[2]);
262       if (mt)
263         {
264           printf ("\n  Description: ");
265           dump_doc (mt);
266           m17n_object_unref (mt);
267         }
268       else
269         printf ("\n  No description");
270
271       title_icon = minput_get_title_icon (tags[1], tags[2]);
272       if (title_icon)
273         {
274           printf ("\n  Title: ");
275           dump_title_icon (title_icon);
276           m17n_object_unref (title_icon);
277         }
278       else
279         printf ("\n  No title nor icon");
280
281       variables = minput_get_variables (tags[1], tags[2]);
282       if (variables)
283         {
284           printf ("\n  Variables:");
285           while ((variables = dump_var (variables)) != NULL);
286         }
287
288       commands = minput_get_commands (tags[1], tags[2]);
289       if (commands)
290         {
291           printf ("\n  Commands:");
292           while ((commands = dump_cmd (commands)) != NULL);
293         }
294
295       if (tags[2] != Mnil)
296         {
297           /* Check if the input method is surely available.   */
298           MInputMethod *im = minput_open_im (tags[1], tags[2], NULL);
299           MInputContext *ic;
300
301           if (! im)
302             fatal ("Can not open\n");
303           ic = minput_create_ic (im, NULL);
304           if (! ic)
305             fatal ("Can not create context\n");
306           minput_destroy_ic (ic);
307           minput_close_im (im);
308         }
309     }
310   printf ("\n#input-methods = %d\n", num);
311   if (plist)
312     m17n_object_unref (plist);
313   M17N_FINI ();
314   exit (0);
315 }