(config_command): Set NAME before using it.
[m17n/m17n-lib.git] / src / language.c
1 /* language.c -- language (and script) module.
2    Copyright (C) 2003, 2004, 2006
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., 51 Franklin Street, Fifth Floor,
21    02111-1307, USA.  */
22
23 #include <config.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <locale.h>
27 #include "m17n.h"
28 #include "m17n-misc.h"
29 #include "internal.h"
30 #include "language.h"
31 #include "symbol.h"
32 #include "plist.h"
33 #include "mtext.h"
34
35 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
36
37 static MPlist *language_list;
38 static MPlist *script_list;
39 static MPlist *langname_list;
40
41 static MPlist *
42 load_lang_script_list (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
43 {
44   MDatabase *mdb = mdatabase_find (tag0, tag1, tag2, tag3);
45   MPlist *plist, *pl, *p;
46
47   if (! mdb
48       || ! (plist = mdatabase_load (mdb)))
49     return NULL;
50   /* Check at least if the plist is ((SYMBOL ...) ...).  */
51   for (pl = plist; ! MPLIST_TAIL_P (pl);)
52     {
53       if (! MPLIST_PLIST_P (pl))
54         mplist__pop_unref (pl);
55       else
56         {
57           p = MPLIST_PLIST (pl);
58           if (! MPLIST_SYMBOL_P (p))
59             mplist__pop_unref (pl);
60           else
61             pl = MPLIST_NEXT (pl);
62         }
63     }
64   return plist;
65 }
66
67 static int
68 init_language_list (void)
69 {
70   language_list = load_lang_script_list (msymbol ("standard"), Mlanguage,
71                                          msymbol ("iso639"), Mnil);
72   if (! language_list)
73     {
74       language_list = mplist ();
75       MERROR (MERROR_DB, -1);
76     }
77   return 0;
78 }
79
80
81 static int
82 init_script_list (void)
83 {
84   script_list = load_lang_script_list (msymbol ("standard"), Mscript,
85                                        msymbol ("unicode"), Mnil);
86   if (! script_list)
87     {
88       script_list = mplist ();
89       MERROR (MERROR_DB, -1);
90     }
91   return 0;
92 }
93
94 \f
95 /* Internal API */
96
97 int
98 mlang__init ()
99 {
100   msymbol_put_func (Mlanguage, Mtext_prop_serializer,
101                     M17N_FUNC (msymbol__serializer));
102   msymbol_put_func (Mlanguage, Mtext_prop_deserializer,
103                     M17N_FUNC (msymbol__deserializer));
104   Miso639_2 = msymbol ("iso639-2");
105   Miso639_1 = msymbol ("iso639-1");
106
107   language_list = script_list = langname_list = NULL;
108   return 0;
109 }
110
111 void
112 mlang__fini (void)
113 {
114   MPlist *pl;
115
116   M17N_OBJECT_UNREF (language_list);
117   M17N_OBJECT_UNREF (script_list);
118   if (langname_list)
119     MPLIST_DO (pl, langname_list)
120       M17N_OBJECT_UNREF (MPLIST_VAL (pl));
121   M17N_OBJECT_UNREF (langname_list);
122 }
123
124 /*=*/
125
126 /***en
127     @brief Get information about a language.
128
129     The mlanguage_info () function returns a well-formed @e plist that
130     contains information about $LANGUAGE.  $LANGUAGE is a symbol whose
131     name is an ISO639-2 3-letter language code, an ISO639-1 2-letter
132     language codes, or an English word.
133
134     The format of the plist is:
135
136 @verbatim
137         (ISO639-2 [ISO639-1 | nil] ENGLISH-NAME ["NATIVE-NAME" | nil]
138                   ["REPRESENTATIVE-CHARACTERS"])
139 @endverbatim
140
141     where, ISO639-2 is a symbol whose name is 3-letter language code
142     of ISO639-2, ISO639-1 is a symbol whose name is 2-letter language
143     code of ISO639-1, ENGLISH-NAME is a symbol whose name is the
144     English name of the language, "NATIVE-NAME" is an M-text written
145     by the most natural way in the language,
146     "REPRESENTATIVE-CHARACTERS" is an M-text that contains
147     representative characters used by the language.
148
149     It is assured that the formats of both M-texts are
150     #MTEXT_FORMAT_UTF_8.
151
152     @return
153     If the information is available, this function returns a plist
154     that should not be modified nor freed.  Otherwise, it returns
155     @c NULL.
156
157     @seealso
158     mlanguage_list ()  */
159
160 MPlist *
161 mlanguage__info (MSymbol language)
162 {
163   MPlist *plist;
164
165   if (! language_list
166       && init_language_list () < 0)
167     return NULL;
168
169   MPLIST_DO (plist, language_list)
170     {
171       MPlist *pl = MPLIST_PLIST (plist);
172
173       if (MPLIST_SYMBOL (pl) == language)
174         return pl;
175       if (MPLIST_TAIL_P (pl))
176         continue;
177       pl = MPLIST_NEXT (pl);
178       if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == language)
179         return MPLIST_PLIST (plist);
180       if (MPLIST_TAIL_P (pl))
181         continue;
182       pl = MPLIST_NEXT (pl);
183       if (MPLIST_MTEXT_P (pl))
184         {
185           MText *mt = MPLIST_MTEXT (pl);
186
187           if (mtext_nbytes (mt) == MSYMBOL_NAMELEN (language)
188               && memcmp (MTEXT_DATA (MPLIST_MTEXT (pl)),
189                          MSYMBOL_NAME (language),
190                          MSYMBOL_NAMELEN (language)) == 0)
191             return MPLIST_PLIST (plist);
192         }
193     }
194   return NULL;
195 }
196
197 static MPlist *
198 mscript__info (MSymbol script)
199 {
200   MPlist *plist;
201
202   if (! script_list
203       && init_script_list () < 0)
204     return NULL;
205   MPLIST_DO (plist, script_list)
206     {
207       MPlist *pl = MPLIST_PLIST (plist);
208
209       if (MPLIST_SYMBOL (pl) == script)
210         return pl;
211     }
212   return NULL;
213 }
214
215 MPlist *
216 mscript__char_list (MSymbol name)
217 {
218   MPlist *plist = mscript__info (name);
219
220   if (plist                     /* script name */
221       && (plist = MPLIST_NEXT (plist)) /* language list */
222       && ! MPLIST_TAIL_P (plist)
223       && (plist = MPLIST_NEXT (plist)) /* char list */
224       && MPLIST_PLIST_P (plist))
225     return MPLIST_PLIST (plist);
226   return NULL;
227 }
228
229 MSymbol
230 mscript__otf_tag (MSymbol script)
231 {
232   MPlist *plist = mscript__info (script);
233
234   if (plist                     /* script name */
235       && (plist = MPLIST_NEXT (plist)) /* language list */
236       && ! MPLIST_TAIL_P (plist)
237       && (plist = MPLIST_NEXT (plist)) /* char list */
238       && ! MPLIST_TAIL_P (plist)
239       && (plist = MPLIST_NEXT (plist)) /* otf tag */
240       && MPLIST_SYMBOL_P (plist))
241     return MPLIST_SYMBOL (plist);
242   return NULL;
243 }
244
245 MSymbol
246 mscript__from_otf_tag (MSymbol otf_tag)
247 {
248   MPlist *plist;
249   /* As it is expected that this function is called in a sequence with
250      the same argument, we use a cache.  */
251   static MSymbol last_otf_tag, script;
252
253   if (! script_list)
254     {
255       last_otf_tag = script = Mnil;
256       if (init_script_list () < 0)
257         return Mnil;
258     }
259   if (otf_tag == last_otf_tag)
260     return script;
261   last_otf_tag = otf_tag;
262   script = Mnil;
263   MPLIST_DO (plist, script_list)
264     {
265       MPlist *pl = MPLIST_PLIST (plist), *p;
266
267       if (pl                           /* script name */
268           && (p = MPLIST_NEXT (pl))    /* language tag */
269           && ! MPLIST_TAIL_P (p)
270           && (p = MPLIST_NEXT (p)) /* char list */
271           && ! MPLIST_TAIL_P (p)
272           && (p = MPLIST_NEXT (p)) /* otf tag */
273           && MPLIST_SYMBOL_P (p)
274           && otf_tag == MPLIST_SYMBOL (p))
275         {
276           script = MPLIST_SYMBOL (pl);
277           break;
278         }
279     }
280   return script;
281 }
282
283 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
284 \f
285
286 /* External API */
287
288 MSymbol Miso639_1, Miso639_2;
289
290 /*=*/
291
292 /***en
293     @brief List 3-letter language codes.
294
295     The mlanguage_list () funciton returns a well-formed plist whose
296     keys are #Msymbol and values are symbols whose names are ISO639-2
297     3-letter language codes.
298
299     @return
300     This function returns a plist.  The caller should free it by
301     m17n_object_unref ().
302
303     @seealso
304     mscript_list ().  */
305
306 /***ja
307     @brief 3ʸ»ú¸À¸ì¥³¡¼¥É¤ò¥ê¥¹¥È¤¹¤ë.
308
309     ´Ø¿ô mlanguage_list () ¤Ï¡¢À°·Á¼° (well-formed) plist ¤òÊÖ¤¹¡£³Æ¥­¡¼
310     ¤Ï #Msymbol ¤Ç¤¢¤ê¡¢¸Ä¡¹¤ÎÃͤϠISO639-2 ¤ËÄê¤á¤é¤ì¤¿3ʸ»ú¸À¸ì¥³¡¼
311     ¥É¤ò̾Á°¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
312
313     @return
314     ¤³¤Î´Ø¿ô¤¬ÊÖ¤¹ plist ¤Ï¡¢¸Æ¤Ó½Ð¤·Â¦¤¬ m17n_object_unref () ¤ò»È¤Ã
315     ¤Æ²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£
316
317     @seealso
318     mscript_list ().  */
319
320 MPlist *
321 mlanguage_list (void)
322 {
323   MPlist *plist, *pl, *p, *p0;
324
325   if (! language_list
326       && init_language_list () < 0)
327     return NULL;
328   plist = pl = mplist ();
329   MPLIST_DO (p, language_list)
330     {
331       p0 = MPLIST_PLIST (p);
332       pl = mplist_add (pl, Msymbol, MPLIST_VAL (p0));
333     }
334   return plist;
335 }
336
337 /*=*/
338
339 /***en
340     @brief Get a language code.
341
342     The mlanguage_code () function returns a symbol whose name is the
343     ISO639 language code of $LANGUAGE. $LANGUAGE is a symbol whose
344     name is an ISO639-2 3-letter language code, an ISO639-1 2-letter
345     language codes, or an English word.
346
347     $LEN specifies the type of the returned language code.  If it is
348     3, an ISO639-2 3-letter language code is returned.  If it is 2, an
349     ISO639-1 2-letter language code is returned when defined;
350     otherwise #Mnil is returned.  If it is 0, a 2-letter code is
351     returned when defined; otherwise a 3-letter code is returned.
352
353     @return
354     If the information is available, this function returns a non-#Mnil
355     symbol.  Otherwise, it returns #Mnil.
356
357     @seealso
358     mlanguage_name_list (), mlanguage_text ().  */
359
360 /***ja
361     @brief ¸À¸ì¥³¡¼¥É¤òÆÀ¤ë.
362
363     ´Ø¿ô mlanguage_code () ¤Ï¡¢$LANGUAGE ¤ËÂбþ¤·¤¿ ISO-639 ¸À¸ì¥³¡¼¥É
364     ¤¬Ì¾Á°¤Ç¤¢¤ë¤è¤¦¤Ê¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£$LANGUAGE ¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¤½¤Î
365     Ì¾Á°¤Ï¡¢ISO639-2 3ʸ»ú¸À¸ì¥³¡¼¥É¡¢ISO639-1 2ʸ»ú¸À¸ì¥³¡¼¥É¡¢±Ñ¸ì̾¡¢
366     ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
367
368     $LEN ¤ÏÊÖ¤µ¤ì¤ë¸À¸ì¥³¡¼¥É¤Î¼ïÎà¤ò·èÄꤹ¤ë¡£$LEN ¤¬3¤Î¾ì¹ç¤Ï 
369     ISO639-2 3ʸ»ú¸À¸ì¥³¡¼¥É¤¬ÊÖ¤µ¤ì¤ë¡£2¤Î¾ì¹ç¤Ï¡¢¤â¤·ÄêµÁ¤µ¤ì¤Æ¤¤¤ì
370     ¤Ð ISO639-1 2ʸ»ú¸À¸ì¥³¡¼¥É¤¬¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð #Mnil ¤¬ÊÖ¤µ¤ì¤ë¡£0 
371     ¤Î¾ì¹ç¤Ï¡¢¤â¤·ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð2ʸ»ú¥³¡¼¥É¤¬¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð3ʸ»ú¥³¡¼
372     ¥É¤¬ÊÖ¤µ¤ì¤ë¡£
373
374     @return
375     ¤â¤·¾ðÊó¤¬ÆÀ¤é¤ì¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï #Mnil °Ê³°¤Î¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¤½¤¦
376     ¤Ç¤Ê¤±¤ì¤Ð #Mnil ¤òÊÖ¤¹¡£
377
378     @seealso
379     mlanguage_name (), mlanguage_text ().  */
380
381 MSymbol
382 mlanguage_code (MSymbol language, int len)
383 {
384   MPlist *plist = mlanguage__info (language);
385   MSymbol code;
386
387   if (! plist)
388     return Mnil;
389   if (! MPLIST_SYMBOL_P (plist))
390     return Mnil;
391   code = MPLIST_SYMBOL (plist);
392   if (len == 3)
393     return code;
394   plist = MPLIST_NEXT (plist);
395   return ((MPLIST_SYMBOL_P (plist) && MPLIST_SYMBOL (plist) != Mnil)
396           ? MPLIST_SYMBOL (plist)
397           : len == 0 ? code : Mnil);
398 }
399
400 /*=*/
401
402 /***en
403     @brief Return the language names written in the specified language.
404
405     The mlanguage_name_list () function returns a plist of LANGUAGE's
406     names written in TARGET language.
407
408     LANGUAGE and TARGET must be a symbol whose name is an ISO639-2
409     3-letter language code or an ISO639-1 2-letter language codes.
410     TARGET may be #Mnil, in which case, the language of the current
411     locale is used.  If locale is not set or is C, English is used.
412
413     @return
414     If the information is available, this function returns a non-empty
415     plist whose keys are #Mtext and values are M-texts of the
416     translated language names.  Otherwise, @c NULL is returned.
417     The returned plist should not be modified nor freed.
418
419     @seealso
420     mlanguage_code (), mlanguage_text ().  */
421
422 MPlist *
423 mlanguage_name_list (MSymbol language, MSymbol target)
424 {
425   MPlist *plist;
426
427   plist = mlanguage__info (language);
428   if (! plist)
429     return NULL;
430   language = mplist_value (plist);
431   if (target != Mnil)
432     {
433       plist = mlanguage__info (target);
434       if (! plist)
435         return NULL;
436       target = mplist_value (plist);
437     }
438   else
439     {
440       MLocale *locale = mlocale_set (LC_MESSAGES, NULL);
441
442       if (! locale)
443         target = msymbol ("eng");
444       else
445         {
446           target = mlocale_get_prop (locale, Mlanguage);
447           plist = mlanguage__info (target);
448           if (! plist)
449             return NULL;
450           target = mplist_value (plist);
451         }
452     }
453   /* Now both LANGUAGE and TARGET are 3-letter codes.  */
454
455   if (langname_list)
456     plist = mplist_get (langname_list, target);
457   else
458     langname_list = mplist (), plist = NULL;
459   if (! plist)
460     {
461       MDatabase *mdb = mdatabase_find (Mlanguage, Mname, target, Mnil);
462
463       if (! mdb
464           || ! (plist = mdatabase_load (mdb)))
465         plist = mplist ();
466       else
467         mplist__pop_unref (plist);
468       langname_list = mplist_push (langname_list, target, plist);
469       MPLIST_SET_NESTED_P (langname_list);
470     }
471   /* PLIST == ((LANGUAGE TRANSLATED) ...) */
472   plist = mplist__assq (plist, language);
473   if (! plist || MPLIST_TAIL_P (plist))
474     return NULL;
475   plist = MPLIST_PLIST (plist);
476   plist = MPLIST_NEXT (plist);
477   return plist;
478 }
479
480 /*=*/
481
482 /***en
483     @brief Return the language name written in that language.
484
485     The mlanguage_text () function returns, in the form of M-text, the
486     language name of $LANGUAGE written in $LANGUAGE.  If the
487     representative characters of the language are known, the
488     characters of the returned M-text has a text property whose key is
489     #Mtext and whose value is an M-text that contains the
490     representative characters.
491
492     @return
493     If the information is available, this function returns an M-text
494     that should not be modified nor freed.  Otherwise, it returns @c
495     NULL.
496
497     @seealso
498     mlanguage_code (), mlanguage_name ().  */
499
500 /***ja
501     @brief Í¿¤¨¤é¤ì¤¿¸À¸ì¼«¿È¤Ç½ñ¤«¤ì¤¿¸À¸ì̾¤òÊÖ¤¹.
502
503     ´Ø¿ô mlanguage_text () ¤Ï¡¢¸À¸ì $LANGUAGE ¤Ç½ñ¤«¤ì¤¿ $LANGUAGE ¤Î
504     Ì¾Á°¤ò M-text ¤Î·Á¼°¤ÇÊÖ¤¹¡£¤½¤Î¸À¸ì¤ÎÂåɽŪ¤Êʸ»ú¤¬¤ï¤«¤Ã¤Æ¤¤¤ë¾ì
505     ¹ç¤Ï¡¢ÊÖ¤µ¤ì¤ë M-text ¤Î³Æʸ»ú¤Ë¡¢¥­¡¼¤¬ #Mtext ¤ÇÃͤ¬¤½¤ÎÂåɽŪ¤Ê
506     Ê¸»ú¤ò´Þ¤à M-text ¤Ç¤¢¤ë¤è¤¦¤Ê¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£¤¬Éղ䵤ì¤ë¡£
507
508     @return
509     µá¤á¤ë¾ðÊó¤¬ÆÀ¤é¤ì¤¿¾ì¹ç¡¢¤³¤Î´Ø¿ô¤¬ÊÖ¤¹ M-text ¤òÊѹ¹¤·¤¿¤ê²òÊü¤·
510     ¤¿¤ê¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡£¾ðÊó¤¬ÆÀ¤é¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï @c NULL ¤¬ÊÖ¤µ¤ì¤ë¡£
511
512     @seealso
513     mlanguage_code (), mlanguage_name ().  */
514
515 MText *
516 mlanguage_text (MSymbol language)
517 {
518   MPlist *plist = mlanguage__info (language);
519   MText *mt;
520
521   if (! plist)
522     return NULL;
523   plist = MPLIST_NEXT (plist);
524   if (MPLIST_TAIL_P (plist))
525     return NULL;
526   plist = MPLIST_NEXT (plist);
527   if (MPLIST_TAIL_P (plist))
528     return NULL;
529   plist = MPLIST_NEXT (plist);            
530   if (! MPLIST_MTEXT_P (plist))
531     return NULL;
532   mt = MPLIST_MTEXT (plist);
533   if (mtext_nchars (mt) == 0)
534     return NULL;
535   plist = MPLIST_NEXT (plist);
536   if (MPLIST_MTEXT_P (plist)
537       && ! mtext_get_prop (mt, 0, Mtext))
538     mtext_put_prop (mt, 0, mtext_nchars (mt), Mtext, MPLIST_MTEXT (plist));
539   return mt;
540 }
541
542 /***en
543     @brief List script names.
544
545     The mscript_list () funciton returns a well-formed plist whose
546     keys are #Msymbol and values are symbols whose names are script
547     names.
548
549     @return
550     This function returns a plist.  The caller should free it by
551     m17n_object_unref ().
552
553     @seealso
554     mscript_language_list (), mlanguage_list ().  */
555
556 /***ja
557     @brief ¥¹¥¯¥ê¥×¥È̾¤ò¥ê¥¹¥È¤¹¤ë.
558
559     ´Ø¿ô mscript_list () ¤Ï¡¢À°·Á¼° (well-formed) plist ¤òÊÖ¤¹¡£³Æ¥­¡¼
560     ¤Ï #Msymbol ¤Ç¤¢¤ê¡¢¸Ä¡¹¤ÎÃͤϥ¹¥¯¥ê¥×¥È̾¤ò̾Á°¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢
561     ¤ë¡£
562
563     @return
564     ¤³¤Î´Ø¿ô¤¬ÊÖ¤¹ plist ¤Ï¡¢¸Æ¤Ó½Ð¤·Â¦¤¬ m17n_object_unref () ¤ò»È¤Ã
565     ¤Æ²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£
566
567     @seealso
568     mscript_language_list (), mlanguage_list ().  */
569
570 MPlist *
571 mscript_list (void)
572 {
573   MPlist *plist, *pl, *p, *p0;
574
575   if (! script_list
576       && init_script_list () < 0)
577     return NULL;
578   plist = pl = mplist ();
579   MPLIST_DO (p, script_list)
580     {
581       p0 = MPLIST_PLIST (p);
582       pl = mplist_add (pl, Msymbol, MPLIST_VAL (p0));
583     }
584   return plist;
585 }
586
587 /*=*/
588
589 /***en
590     @brief List languages that use a specified script.
591
592     The mscript_language_list () function lists languages that use
593     $SCRIPT.  $SCRIPT is a symbol whose name is the lower-cased
594     version of a script name that appears in the Unicode Character
595     Database.
596
597     @return
598
599     This function returns a well-formed plist whose keys are #Msymbol
600     and values are symbols whose names are ISO639-1 2-letter codes (or
601     ISO639-2 3-letter codes, if the former is not available).  The
602     caller should not modify nor free it.  If the m17n library does
603     not know about $SCRIPT, it returns @ c NULL.
604
605     @seealso
606     mscript_list (), mlanguage_list ().  */
607
608 /***ja
609     @brief Í¿¤¨¤é¤ì¤¿¥¹¥¯¥ê¥×¥È¤òÍѤ¤¤ë¸À¸ì¤ò¥ê¥¹¥È¤¹¤ë.
610
611     ´Ø¿ô mscript_language_list () ¤Ï¡¢$SCRIPT ¤òÍѤ¤¤ë¸À¸ì¤ò¥ê¥¹¥È¤¹¤ë¡£
612     $SCRIPT ¤Ï¥·¥ó¥Ü¥ë¤Ç¡¢¤½¤Î̾Á°¤Ï Unicode Character Database ¤Ë¼¨¤µ
613     ¤ì¤Æ¤¤¤ë¥¹¥¯¥ê¥×¥È̾¤ò¤¹¤Ù¤Æ¾®Ê¸»ú¤Ë¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£
614
615     @return ¤³¤Î´Ø¿ô¤Ï¡¢À°·Á¼° (well-formed) plist ¤òÊÖ¤¹¡£³Æ¥­¡¼¤Ï 
616     #Msymbol ¤Ç¤¢¤ê¡¢¸Ä¡¹¤ÎÃͤϠISO639-1 ¤ËÄê¤á¤é¤ì¤¿2ʸ»ú¸À¸ì¥³¡¼¥É
617     (ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï ISO639-2 ¤ËÄê¤á¤é¤ì¤¿3ʸ»ú¸À¸ì¥³¡¼¥É) ¤ò̾
618     Á°¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ÊÖ¤µ¤ì¤ë plist ¤ÏÊѹ¹¤·¤¿¤ê²òÊü¤·¤¿¤ê¤·¤Æ
619     ¤Ï¤Ê¤é¤Ê¤¤¡£$SCRIPT ¤¬Ì¤ÃΤξì¹ç¤Ï @c NULL ¤¬ÊÖ¤µ¤ì¤ë¡£
620
621     @seealso
622     mscript_list (), mlanguage_list ().  */
623     
624
625 MPlist *
626 mscript_language_list (MSymbol script)
627 {
628   MPlist *plist = mscript__info (script);
629
630   if (plist                     /* script name */
631       && (plist = MPLIST_NEXT (plist)) /* language list */
632       && MPLIST_PLIST_P (plist))
633     return MPLIST_PLIST (plist);
634   return NULL;
635 }
636
637 /*** @} */
638 /*=*/
639 /***en
640     @name Obsolete functions
641 */
642 /***ja
643     @name Obsolete ¤Ê´Ø¿ô
644 */
645 /*** @{ */
646
647 /***en
648     @brief Get an English language name.
649
650     This function is obsolete.  Use mlanguage_name_list () instead.
651
652     The mlanguage_name () function returns a symbol whose name is an
653     English name of $LANGUAGE.  $LANGUAGE is a symbol whose name is an
654     ISO639-2 3-letter language code, an ISO639-1 2-letter language
655     codes, or an English word.
656
657     @return
658     If the information is available, this function returns a non-#Mnil
659     symbol.  Otherwise, it returns #Mnil.
660
661     @seealso
662     mlanguage_code (), mlanguage_text ().  */
663
664 /***ja
665     @brief ¸À¸ì¤Î±Ñ¸ì̾¤òÆÀ¤ë.
666
667     ´Ø¿ô mlanguage_name () ¤Ï¡¢$LANGUAGE ¤Î±Ñ¸ì̾¤ò̾Á°¤È¤¹¤ë¤è¤¦¤Ê¥·
668     ¥ó¥Ü¥ë¤òÊÖ¤¹¡£$LANGUAGE ¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¤½¤Î̾Á°¤Ï¡¢ISO639-2 3ʸ
669     »ú¸À¸ì¥³¡¼¥É¡¢ISO639-1 2ʸ»ú¸À¸ì¥³¡¼¥É¡¢±Ñ¸ì̾¡¢¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
670
671     @return
672     µá¤á¤Æ¤¤¤ë¾ðÊó¤¬ÆÀ¤é¤ì¤ë¤Ê¤é¡¢¤³¤Î´Ø¿ô¤Ï #Mnil °Ê³°¤Î¥·¥ó¥Ü¥ë¤òÊÖ
673     ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð #Mnil ¤òÊÖ¤¹¡£
674
675     @seealso
676     mlanguage_code (), mlanguage_text ().  */
677
678 MSymbol
679 mlanguage_name (MSymbol language)
680 {
681   MPlist *plist = mlanguage__info (language);
682   MText *mt;
683
684   if (! plist)                  /* 3-letter code */
685     return Mnil;
686   plist = MPLIST_NEXT (plist);  /* 2-letter code */
687   if (MPLIST_TAIL_P (plist))
688     return Mnil;
689   plist = MPLIST_NEXT (plist);  /* english name */
690   if (MPLIST_MTEXT_P (plist))
691     return Mnil;
692   mt = MPLIST_MTEXT (plist);
693   if (mtext_nbytes (mt) != MSYMBOL_NAMELEN (language)
694       || memcmp (MTEXT_DATA (MPLIST_MTEXT (plist)),
695                  MSYMBOL_NAME (language),
696                  MSYMBOL_NAMELEN (language)))
697     return Mnil;
698   return language;
699 }
700
701 /*=*/
702
703 /*
704   Local Variables:
705   coding: euc-japan
706   End:
707 */