1
/* locale.c -- locale module.
2
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3
National Institute of Advanced Industrial Science and Technology (AIST)
4
Registration Number H15PRO112
6
This file is part of the m17n library.
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.
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.
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,
24
@addtogroup m17nLocale
25
@brief Locale objects and API for them.
27
The m17n library represents locale related information as objects
31
@addtogroup m17nLocale
32
@brief �������륪�֥������ȤȤ���˴ؤ��� API.
34
m17n �饤�֥��ϥ��������Ϣ����� #MLocale ���Υ��֥������Ȥ�ɽ�����롣 */
38
#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
39
/*** @addtogroup m17nInternal
49
#ifdef HAVE_LANGINFO_H
55
#include "m17n-misc.h"
62
static MSymbol M_locale;
63
static MSymbol M_xfrm;
66
/** Structure of locales. */
80
/** The current locales of each category. */
81
MLocale *mlocale__collate, *mlocale__ctype;
82
MLocale *mlocale__messages, *mlocale__time;
84
/* These are currently not used. */
86
MLocale *mlocale_monetary, *mlocale_numeric, ;
89
/** Parse locale name NAME and return a newly created MLocale object.
90
If the locale is not supported by the system, return NULL. */
93
make_locale (const char *name)
95
char *current, *new, *str;
100
str = setlocale (LC_CTYPE, NULL);
101
len = strlen (str) + 1;
102
current = alloca (len);
103
memcpy (current, str, len);
105
if (! (new = setlocale (LC_CTYPE, name)))
109
M17N_OBJECT (locale, NULL, MERROR_LOCALE);
110
locale->name = msymbol (new);
111
msymbol_put (locale->name, M_locale, (void *) locale);
112
M17N_OBJECT_UNREF (locale);
114
len = strlen (new) + 1;
116
memcpy (str, new, len);
124
for (i = 0; str[i]; i++)
125
if (str[i] == '_' || str[i] == '.' || str[i] == '@')
130
/* The first field is for language. */
131
locale->language = msymbol (str);
133
/* The field following '_' is for territory. */
134
locale->territory = msymbol (str);
136
/* The field following '.' is for codeset. */
137
locale->codeset = msymbol (str);
139
/* The other field is for modifier. */
140
locale->modifier = msymbol (str);
147
#ifdef HAVE_NL_LANGINFO
149
/* If we can use nl_langinfo () to retrieve a codeset name, respect
150
it over the codeset name extracted from the locale name. */
151
locale->codeset = msymbol (nl_langinfo (CODESET));
155
/* If the locale name specifies a codeset, get the corresponding
157
if (locale->codeset != Mnil)
159
locale->coding = mconv_resolve_coding (locale->codeset);
160
if (locale->coding == Mnil)
161
locale->coding = Mcoding_us_ascii;
164
locale->coding = Mcoding_us_ascii;
166
setlocale (LC_CTYPE, current);
171
/** Decode the byte sequence at BUF of length SIZE bytes by the coding
172
system associated with LOCALE, and return a generated M-text. */
175
decode_locale (unsigned char *buf, int size, MLocale *locale)
177
return mconv_decode_buffer (locale->coding, buf, size);
181
/** Encode the M-text MT by the coding system associated with LOCALE,
182
and store the resulting bytes in the memory area at BUF of *SIZE
183
bytes. If the area is too short, allocate a new and wider area.
184
Store the length of the generated bytes in the place pointed by
185
SIZE, and return the address of those bytes. */
187
static unsigned char *
188
encode_locale (MText *mt, unsigned char *buf, int *size, MLocale *locale)
190
int nbytes = mconv_encode_buffer (locale->coding, mt, buf, *size - 1);
197
MTABLE_REALLOC (buf, *size, MERROR_LOCALE);
198
nbytes = mconv_encode_buffer (mlocale__ctype->coding, mt, buf,
200
} while (nbytes < 0);
208
/** Structure of transformed strings. The function mtext_coll ()
209
caches this object in an M-text as a text property. */
212
/* Common header for a managed object. */
215
/* Locale corresponding to <str>. */
218
/** Result of strxfrm. */
224
free_xfrm (void *object)
226
MXfrm *xfrm = (MXfrm *) object;
228
M17N_OBJECT_UNREF (xfrm->locale);
235
MTextProperty *prop = mtext_get_property (mt, 0, M_xfrm);
238
unsigned char *buf, *newbuf;
243
if (prop->end == mt->nchars)
245
xfrm = (MXfrm *) prop->val;
246
if (xfrm->locale == mlocale__ctype)
249
mtext_detach_property (prop);
254
newbuf = encode_locale (mt, buf, &size, mlocale__ctype);
255
M17N_OBJECT (xfrm, free_xfrm, MERROR_MTEXT);
256
xfrm->str = malloc (size);
257
request = strxfrm (xfrm->str, (char *) newbuf, size);
260
xfrm->str = realloc (xfrm->str, request);
261
strxfrm (xfrm->str, (char *) newbuf, size);
265
prop = mtext_property (M_xfrm, xfrm, MTEXTPROP_VOLATILE_WEAK);
266
mtext_attach_property (mt, 0, mt->nchars, prop);
267
M17N_OBJECT_UNREF (prop);
277
M_locale = msymbol_as_managing_key (" locale");
279
Mterritory = msymbol ("territory");
280
Mcodeset = msymbol ("codeset");
282
mlocale__collate = mlocale_set (LC_COLLATE, NULL);
283
M17N_OBJECT_REF (mlocale__collate);
284
mlocale__ctype = mlocale_set (LC_CTYPE, NULL);
285
M17N_OBJECT_REF (mlocale__ctype);
286
mlocale__messages = mlocale_set (LC_MESSAGES, NULL);
287
M17N_OBJECT_REF (mlocale__messages);
288
mlocale__time = mlocale_set (LC_TIME, NULL);
289
M17N_OBJECT_REF (mlocale__time);
291
M_xfrm = msymbol_as_managing_key (" xfrm");
298
M17N_OBJECT_UNREF (mlocale__collate);
299
M17N_OBJECT_UNREF (mlocale__ctype);
300
M17N_OBJECT_UNREF (mlocale__messages);
301
M17N_OBJECT_UNREF (mlocale__time);
305
#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
309
/*** @addtogroup m17nLocale */
313
/***en The symbol whose name is "territory". */
314
/***ja "territory" �Ȥ���̾������ĥ���ܥ�. */
318
/***en The symbol whose name is "modifier". */
319
/***ja "modifier" �Ȥ���̾������ĥ���ܥ�. */
323
/***en The symbol whose name is "codeset". */
324
/***ja "codeset" �Ȥ���̾������ĥ���ܥ�. */
330
@brief Set the current locale.
332
The mlocale_set () function sets or query a part of the current
333
locale. The part is specified by $CATEGORY which must be a valid
334
first argument to <tt>setlocale ()</tt>.
336
If $LOCALE is not NULL, the locale of the specified part is set to
337
$LOCALE. If $LOCALE is not supported by the system, the current
338
locale is not changed.
340
If $LOCALE is NULL, the current locale of the specified part is
344
If the call is successful, mlocale_set () returns an opaque locale
345
object that corresponds to the locale. The name of the locale can
346
be acquired by the function mlocale_get_prop ().
347
Otherwise, it returns NULL. */
350
@brief ���ߤΥ�����������ꤹ��.
352
�ؿ� mlocale_set () �ϸ��ߤΥ�������ΰ��������ꤷ�����䤤��碌���ꤹ�롣�����ǰ����Ȥ�
353
$CATEGORY �ǻ��ꤵ�졢<tt>setlocale ()</tt> ��ͭ�����������Ȥʤ��ΤǤʤ��ƤϤʤ�ʤ���
355
$LOCALE �� NULL �Ǥʤ���С����ꤷ����ʬ�Υ������뤬$LOCALE �����ꤵ��롣
356
$LOCALE �������ƥ�˥��ݡ��Ȥ���Ƥ��ʤ���С�����ϹԤ�줺�����ߤΥ���������Ѥ��ʤ���
358
$LOCALE �� NULL �ʤ�С����ߤΥ�������λ��ꤷ����ʬ���䤤��碌�롣
362
�ƤӽФ�����������С�mlocale_set () �ϥ���������б����� opaque
363
�������륪�֥������Ȥ��֤������������̾���ϴؿ�
364
mlocale_get_prop () �ˤ�ä����뤳�Ȥ��Ǥ��롣
365
�����Ǥʤ���� NULL ���֤���
373
mlocale_set (int category, const char *name)
378
new = setlocale (category, name);
382
locale = (MLocale *) msymbol_get (msymbol (new), M_locale);
384
locale = make_locale (new);
387
if (name && (category == LC_ALL || category == LC_COLLATE))
389
M17N_OBJECT_REF (locale);
390
M17N_OBJECT_UNREF (mlocale__collate);
391
mlocale__collate = locale;
393
else if (name && (category == LC_ALL || category == LC_CTYPE))
395
M17N_OBJECT_REF (locale);
396
M17N_OBJECT_UNREF (mlocale__ctype);
397
mlocale__ctype = locale;
399
if (name && (category == LC_ALL || category == LC_MESSAGES))
401
M17N_OBJECT_REF (locale);
402
M17N_OBJECT_UNREF (mlocale__messages);
403
mlocale__messages = locale;
405
if (name && (category == LC_ALL || category == LC_TIME))
407
M17N_OBJECT_REF (locale);
408
M17N_OBJECT_UNREF (mlocale__time);
409
mlocale__time = locale;
417
@brief Get the value of a locale property.
419
The mlocale_get_prop () function returns the value of a property
420
$KEY of local $LOCALE. $KEY must be #Mname, #Mlanguage,
421
#Mterritory, #Mcodeset, #Mmodifier, or #Mcoding. */
424
@brief ��������ץ��ѥƥ����ͤ�����.
426
�ؿ� mlocale_get_prop () �ϡ��������� $LOCALE �� $KEY �ץ��ѥƥ����ͤ��֤���
427
$KEY �� #Mname, #Mlanguage, #Mterritory, #Mcodeset, #Mmodifier,
428
#Mcoding �Τ����줫�Ǥ��롣 */
431
mlocale_get_prop (MLocale *locale, MSymbol key)
434
return locale->coding;
437
if (key == Mlanguage)
438
return locale->language;
439
if (key == Mterritory)
440
return locale->territory;
442
return locale->codeset;
443
if (key == Mmodifier)
444
return locale->modifier;
450
@brief Format date and time.
452
The mtext_ftime () function formats the broken-down time $TM
453
according to the format specification $FORMAT and append the
454
result to the M-text $MT. The formating is done according to the
455
locale $LOCALE (if not NULL) or the current locale (LC_TIME).
457
The meaning of the arguments $TM and $FORMAT are the same as those
464
@brief ���դȻ��֤�ե����ޥåȤ���.
466
�ؿ� mtext_ftime () �ϻ���ǡ��� (broken-down time) $TM ��$FORMAT
467
�ǻ��ꤵ�줿������������̤�M-text $MT ���ղä��롣�ե����ޥåȤ�
468
NULL �Ǥʤ���� �������� $LOCALE �ˡ��ޤ��ϸ��ߤΥ�������(LC_TIME) �˽�����
470
���� $TM �� $FORMAT �ΰ�̣�� strftime () �ξ���Ʊ����
477
mtext_ftime (MText *mt, const char *format, const struct tm *tm,
482
size_t nbytes, nchars;
483
char *current_locale = NULL;
487
char *str = setlocale (LC_TIME, NULL);
488
int len = strlen (str) + 1;
490
current_locale = alloca (len);
491
memcpy (current_locale, str, len);
492
mlocale_set (LC_TIME, msymbol_name (locale->name));
498
MTABLE_ALLOCA (buf, bufsize, MERROR_MTEXT);
500
nbytes = strftime ((char *) buf, bufsize, format, tm);
509
MText *work = decode_locale (buf, nbytes, mlocale__time);
513
nchars = work->nchars;
514
mtext_cat (mt, work);
515
M17N_OBJECT_UNREF (work);
524
mlocale_set (LC_TIME, current_locale);
532
@brief Get an environment variable.
534
The mtext_getenv () function searches the environment variable
535
list for a string that matches the string pointed to by $NAME.
537
If there is a match, the function decodes the value according to
538
the current locale (LC_CTYPE) into an M-text, and return that
541
If there is no match, the function returns NULL. */
545
�ؿ� mtext_getenv () �� $NAME
546
�ǻؤ����ʸ����ȹ��פ���ʸ�����Ķ��ѿ��Υꥹ���椫��õ����
548
���Ĥ��ä����ˤϡ������ͤߤΥ�������(LC_CTYPE) �˽��ä�
549
M-text �˥ǥ����ɤ�������M-text ���֤���
551
���Ĥ���ʤ���С�NULL ���֤��� */
554
mtext_getenv (const char *name)
556
char *p = getenv (name);
560
return decode_locale ((unsigned char *) p, strlen (p), mlocale__ctype);
566
@brief Change or add an environment variable.
568
The mtext_putenv () function changes or adds the value of
569
environment variables according to M-text $MT. It calls the
570
function <tt>putenv</tt> with an argument generated by encoding
571
$MT according to the current locale (LC_CTYPE).
574
This function returns zero on success, or -1 if an error
577
@brief �Ķ��ѿ����ѹ����ɲä���.
579
�ؿ� mtext_putenv () �� M-text $MT
580
�˽��äơ��Ķ��ѿ����ͤ��ѹ��������ɲä����ꤹ�롣���δؿ��ϡ����ߤΥ�������
581
(LC_CTYPE) �˽��ä�$MT ���ɤ������������Ȥ��ƴؿ� <tt>putenv</tt> ��Ƥ֡�
584
���δؿ��ϡ������������ˤ� 0 ���顼��������� -1 ���֤���
589
mtext_putenv (MText *mt)
591
unsigned char buf[1024];
593
unsigned char *newbuf;
596
newbuf = encode_locale (mt, buf, &size, mlocale__ctype);
597
result = putenv ((char *) newbuf);
606
@brief Compare two M-texts using the current locale.
608
The mtext_coll () function compares the two M-texts $MT1 and $MT2.
609
It returns an integer less than, equal to, or greater than zero if
610
$MT1 is found, respectively, to be less than, to match, or to be
611
greater than $MT2. The comparison is based on texts as
612
appropriate for the current locale (LC_COLLATE).
614
This function makes use of information that is automatically
615
cached in the M-texts as a text property. So, the second call of
616
this function with $MT1 or $MT2 finishes faster than the first
619
@brief ���ߤΥ���������Ѥ��ƣ��Ĥ� M-text ����Ӥ���.
621
�ؿ� mtext_coll () �ϣ��Ĥ� M-text $MT1 �� $MT2
622
����Ӥ��롣����ͤ����������, 0, ���������ͤΤ����줫�Ǥ��ꡢ���줾��
623
$MT1 �� $MT2 ��꾮������Ʊ�����礭�������������롣��Ӥϸ��ߤΥ�������
624
(LC_COLLATE) �˴�Ť��ƹԤ��롣
627
�Υƥ����ȥץ��ѥƥ��Ȥ��Ƽ�ưŪ�˥���å��夵����������Ѥ���Τǡ������ܰʹߤ�Ʊ����Ӥϣ����ܤ��®���¹Ԥ���롣 */
630
mtext_coll (MText *mt1, MText *mt2)
634
if (mt1->nchars == 0)
635
return (mt2->nchars == 0 ? 0 : -1);
636
else if (mt2->nchars == 0)
639
str1 = get_xfrm (mt1);
640
str2 = get_xfrm (mt2);
641
return strcoll (str1, str2);