Include "plist.h".
[m17n/m17n-lib.git] / src / language.c
1 /* language.c -- language module.
2    Copyright (C) 2003, 2004
3      National Institute of Advanced Industrial Science and Technology (AIST)
4      Registration Number H15PRO112
5
6    This file is part of the m17n library.
7
8    The m17n library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public License
10    as published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    The m17n library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with the m17n library; if not, write to the Free
20    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 #include <config.h>
24 #include <stdlib.h>
25 #include "m17n.h"
26 #include "m17n-misc.h"
27 #include "internal.h"
28 #include "language.h"
29 #include "symbol.h"
30 #include "plist.h"
31
32 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
33
34 static MSymbol M_script_lang_list;
35
36 \f
37 /* Internal API */
38
39 int
40 mlang__init ()
41 {
42   MDatabase *mdb;
43   MPlist *plist, *pl;
44
45   Mlanguage = msymbol ("language");
46   msymbol_put (Mlanguage, Mtext_prop_serializer,
47                (void *) msymbol__serializer);
48   msymbol_put (Mlanguage, Mtext_prop_deserializer,
49                (void *) msymbol__deserializer);
50   Miso639_2 = msymbol ("iso639-2");
51   Miso639_1 = msymbol ("iso639-1");
52   M_script_lang_list = msymbol_as_managing_key ("  script-lang-list");
53
54   mdb = mdatabase_find (msymbol ("standard"), Mlanguage,
55                         msymbol ("iso639"), Mnil);
56   if (! mdb)
57     return 0;
58   if (! (plist = mdatabase_load (mdb)))
59     MERROR (MERROR_DB, -1);
60
61   MPLIST_DO (pl, plist)
62     {
63       MPlist *p;
64       MSymbol code3, code2, lang;
65       MText *native;
66
67       if (! MPLIST_PLIST_P (pl))
68         continue;
69       p = MPLIST_PLIST (pl);
70       if (! MPLIST_SYMBOL_P (p))
71         continue;
72       code3 = MPLIST_SYMBOL (p);
73       p = MPLIST_NEXT (p);
74       if (! MPLIST_SYMBOL_P (p))
75         continue;
76       code2 = MPLIST_SYMBOL (p);
77       p = MPLIST_NEXT (p);
78       if (! MPLIST_SYMBOL_P (p))
79         continue;
80       lang = MPLIST_SYMBOL (p);
81       msymbol_put (code3, Mlanguage, lang);
82       p = MPLIST_NEXT (p);      
83       native = MPLIST_MTEXT_P (p) ? MPLIST_MTEXT (p) : NULL;
84       if (native)
85         msymbol_put (code3, Mtext, native);
86       if (code2 != Mnil)
87         {
88           msymbol_put (code3, Miso639_1, code2);
89           msymbol_put (code2, Mlanguage, lang);
90           msymbol_put (code2, Miso639_2, code3);
91           if (native)
92             msymbol_put (code2, Mtext, native);
93         }
94     }
95   M17N_OBJECT_UNREF (plist);
96   return 0;
97 }
98
99 void
100 mlang__fini (void)
101 {
102 }
103
104
105 /** Return a plist of languages that use SCRIPT.  If SCRIPT is Mnil,
106     return a plist of all languages.  Each element of the plist has
107     3-letter language code as a key and 2-letter language code as a
108     value.  A caller must unref the returned value when finished.  */
109
110 MPlist *
111 mlanguage__list (MSymbol script)
112 {
113   MDatabase *mdb;
114   MPlist *language_list, *plist, *pl;
115
116   if (script)
117     {
118       if ((language_list = msymbol_get (script, M_script_lang_list)))
119         {
120           M17N_OBJECT_REF (language_list);
121           return language_list;
122         }
123       mdb = mdatabase_find (msymbol ("unicode"), Mscript, Mlanguage, Mnil);
124       if (! mdb
125           || ! (plist = mdatabase_load (mdb)))
126         MERROR (MERROR_DB, NULL);
127       MPLIST_DO (pl, plist)
128         {
129           MPlist *p, *lang_list;
130           MSymbol code3, code2;
131
132           if (! MPLIST_PLIST_P (pl))
133             continue;
134           p = MPLIST_PLIST (pl);
135           if (! MPLIST_SYMBOL_P (p))
136             continue;
137           lang_list = mplist ();
138           if (MPLIST_SYMBOL (p) == script)
139             language_list = lang_list;
140           msymbol_put (MPLIST_SYMBOL (p), M_script_lang_list, lang_list);
141           MPLIST_DO (p, MPLIST_NEXT (p))
142             if (MPLIST_SYMBOL_P (p))
143               {
144                 code2 = MPLIST_SYMBOL (p);
145                 if (MSYMBOL_NAMELEN (code2) == 2)
146                   code3 = msymbol_get (code2, Miso639_2);
147                 else
148                   code3 = code2, code2 = Mnil;
149                 if (code3 != Mnil)
150                   mplist_push (lang_list, code3, code2);
151               }
152           M17N_OBJECT_UNREF (lang_list);
153         }
154       M17N_OBJECT_UNREF (plist);
155       if (language_list)
156         M17N_OBJECT_REF (language_list);
157       else
158         {
159           language_list = mplist ();
160           msymbol_put (script, M_script_lang_list, language_list);
161         }
162     }
163   else
164     {
165       mdb = mdatabase_find (msymbol ("standard"), Mlanguage,
166                             msymbol ("iso639"), Mnil);
167       if (! mdb
168           || ! (plist = mdatabase_load (mdb)))
169         MERROR (MERROR_DB, NULL);
170       MPLIST_DO (pl, plist)
171         {
172           MPlist *p;
173           MSymbol code3, code2;
174
175           if (! MPLIST_PLIST_P (pl))
176             continue;
177           p = MPLIST_PLIST (pl);
178           if (! MPLIST_SYMBOL_P (p))
179             continue;
180           code3 = MPLIST_SYMBOL (p);
181           p = MPLIST_NEXT (p);
182           if (! MPLIST_SYMBOL_P (p))
183             continue;
184           code2 = MPLIST_SYMBOL (p);
185           mplist_push (language_list, code3, code2);
186         }
187       M17N_OBJECT_UNREF (plist);
188     }
189   return language_list;
190 }
191
192 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
193 \f
194
195 /* External API */
196
197 MSymbol Miso639_1, Miso639_2;