xref: /onnv-gate/usr/src/lib/libc/port/i18n/gettext.c (revision 6812:febeba71273d)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
54843Sraf  * Common Development and Distribution License (the "License").
64843Sraf  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
214843Sraf 
220Sstevel@tonic-gate /*
23*6812Sraf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
29*6812Sraf #pragma weak _bindtextdomain = bindtextdomain
30*6812Sraf #pragma weak _textdomain = textdomain
31*6812Sraf #pragma weak _gettext = gettext
32*6812Sraf #pragma weak _dgettext = dgettext
33*6812Sraf #pragma weak _dcgettext = dcgettext
34*6812Sraf #pragma weak _ngettext = ngettext
35*6812Sraf #pragma weak _dngettext = dngettext
36*6812Sraf #pragma weak _dcngettext = dcngettext
37*6812Sraf #pragma weak _bind_textdomain_codeset = bind_textdomain_codeset
380Sstevel@tonic-gate 
39*6812Sraf #include "lint.h"
400Sstevel@tonic-gate #include "mtlib.h"
410Sstevel@tonic-gate #include <errno.h>
420Sstevel@tonic-gate #include <ctype.h>
430Sstevel@tonic-gate #include <locale.h>
440Sstevel@tonic-gate #include <stdio.h>
450Sstevel@tonic-gate #include <stdlib.h>
460Sstevel@tonic-gate #include <sys/types.h>
470Sstevel@tonic-gate #include <sys/param.h>
480Sstevel@tonic-gate #include <libintl.h>
490Sstevel@tonic-gate #include <thread.h>
500Sstevel@tonic-gate #include <synch.h>
510Sstevel@tonic-gate #include "libc.h"
520Sstevel@tonic-gate #include "_loc_path.h"
530Sstevel@tonic-gate #include "msgfmt.h"
540Sstevel@tonic-gate #include "gettext.h"
550Sstevel@tonic-gate 
560Sstevel@tonic-gate #define	INIT_GT(def) \
570Sstevel@tonic-gate 	if (!global_gt) { \
580Sstevel@tonic-gate 		global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \
590Sstevel@tonic-gate 		if (global_gt) \
600Sstevel@tonic-gate 			global_gt->cur_domain = (char *)default_domain; \
610Sstevel@tonic-gate 		else { \
625002Sraf 			callout_lock_exit(); \
630Sstevel@tonic-gate 			return ((def)); \
640Sstevel@tonic-gate 		} \
650Sstevel@tonic-gate 	}
660Sstevel@tonic-gate 
670Sstevel@tonic-gate const char	*defaultbind = DEFAULT_BINDING;
680Sstevel@tonic-gate const char	default_domain[] = DEFAULT_DOMAIN;
690Sstevel@tonic-gate Gettext_t	*global_gt = NULL;
700Sstevel@tonic-gate 
710Sstevel@tonic-gate char *
bindtextdomain(const char * domain,const char * binding)72*6812Sraf bindtextdomain(const char *domain, const char *binding)
730Sstevel@tonic-gate {
740Sstevel@tonic-gate 	char	*res;
750Sstevel@tonic-gate 
765002Sraf 	callout_lock_enter();
770Sstevel@tonic-gate 	INIT_GT(NULL);
780Sstevel@tonic-gate 	res = _real_bindtextdomain_u(domain, binding, TP_BINDING);
795002Sraf 	callout_lock_exit();
800Sstevel@tonic-gate 	return (res);
810Sstevel@tonic-gate }
820Sstevel@tonic-gate 
830Sstevel@tonic-gate char *
bind_textdomain_codeset(const char * domain,const char * codeset)84*6812Sraf bind_textdomain_codeset(const char *domain, const char *codeset)
850Sstevel@tonic-gate {
860Sstevel@tonic-gate 	char	*res;
870Sstevel@tonic-gate 
885002Sraf 	callout_lock_enter();
890Sstevel@tonic-gate 	INIT_GT(NULL);
900Sstevel@tonic-gate 	res = _real_bindtextdomain_u(domain, codeset, TP_CODESET);
915002Sraf 	callout_lock_exit();
920Sstevel@tonic-gate 	return (res);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate  * textdomain() sets or queries the name of the current domain of
970Sstevel@tonic-gate  * the active LC_MESSAGES locale category.
980Sstevel@tonic-gate  */
990Sstevel@tonic-gate char *
textdomain(const char * domain)100*6812Sraf textdomain(const char *domain)
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate 	char	*res;
1030Sstevel@tonic-gate 	char	tmp_domain[TEXTDOMAINMAX + 1];
1040Sstevel@tonic-gate 
1055002Sraf 	callout_lock_enter();
1060Sstevel@tonic-gate 	INIT_GT(NULL);
1070Sstevel@tonic-gate 	res = _textdomain_u(domain, tmp_domain);
1080Sstevel@tonic-gate 	if (res == NULL) {
1095002Sraf 		callout_lock_exit();
1100Sstevel@tonic-gate 		return (NULL);
1110Sstevel@tonic-gate 	}
1125002Sraf 	callout_lock_exit();
1130Sstevel@tonic-gate 	return (CURRENT_DOMAIN(global_gt));
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate /*
1170Sstevel@tonic-gate  * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed
1180Sstevel@tonic-gate  * for domain and LC_MESSAGES passed for category.
1190Sstevel@tonic-gate  */
1200Sstevel@tonic-gate char *
gettext(const char * msg_id)121*6812Sraf gettext(const char *msg_id)
1220Sstevel@tonic-gate {
1230Sstevel@tonic-gate 	char	*res;
1240Sstevel@tonic-gate 	int	errno_save = errno;
1250Sstevel@tonic-gate 
1265002Sraf 	callout_lock_enter();
1270Sstevel@tonic-gate 	INIT_GT((char *)msg_id);
1280Sstevel@tonic-gate 	res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0);
1295002Sraf 	callout_lock_exit();
1300Sstevel@tonic-gate 	errno = errno_save;
1310Sstevel@tonic-gate 	return (res);
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate  * In dcgettext() call, domain is valid only for this call.
1370Sstevel@tonic-gate  */
1380Sstevel@tonic-gate char *
dgettext(const char * domain,const char * msg_id)139*6812Sraf dgettext(const char *domain, const char *msg_id)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate 	char	*res;
1420Sstevel@tonic-gate 	int	errno_save = errno;
1430Sstevel@tonic-gate 
1445002Sraf 	callout_lock_enter();
1450Sstevel@tonic-gate 	INIT_GT((char *)msg_id);
1460Sstevel@tonic-gate 	res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0);
1475002Sraf 	callout_lock_exit();
1480Sstevel@tonic-gate 	errno = errno_save;
1490Sstevel@tonic-gate 	return (res);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate char *
dcgettext(const char * domain,const char * msg_id,const int category)153*6812Sraf dcgettext(const char *domain, const char *msg_id, const int category)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate 	char	*res;
1560Sstevel@tonic-gate 	int	errno_save = errno;
1570Sstevel@tonic-gate 
1585002Sraf 	callout_lock_enter();
1590Sstevel@tonic-gate 	INIT_GT((char *)msg_id);
1600Sstevel@tonic-gate 	res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0);
1615002Sraf 	callout_lock_exit();
1620Sstevel@tonic-gate 	errno = errno_save;
1630Sstevel@tonic-gate 	return (res);
1640Sstevel@tonic-gate }
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate char *
ngettext(const char * msgid1,const char * msgid2,unsigned long int n)167*6812Sraf ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
1680Sstevel@tonic-gate {
1690Sstevel@tonic-gate 	char	*res;
1700Sstevel@tonic-gate 	int	errno_save = errno;
1710Sstevel@tonic-gate 
1725002Sraf 	callout_lock_enter();
1730Sstevel@tonic-gate 	INIT_GT((char *)msgid1);
1740Sstevel@tonic-gate 	res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1);
1755002Sraf 	callout_lock_exit();
1760Sstevel@tonic-gate 	errno = errno_save;
1770Sstevel@tonic-gate 	return (res);
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate char *
dngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n)181*6812Sraf dngettext(const char *domain, const char *msgid1, const char *msgid2,
1820Sstevel@tonic-gate 	unsigned long int n)
1830Sstevel@tonic-gate {
1840Sstevel@tonic-gate 	char	*res;
1850Sstevel@tonic-gate 	int	errno_save = errno;
1860Sstevel@tonic-gate 
1875002Sraf 	callout_lock_enter();
1880Sstevel@tonic-gate 	INIT_GT((char *)msgid1);
1890Sstevel@tonic-gate 	res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1);
1905002Sraf 	callout_lock_exit();
1910Sstevel@tonic-gate 	errno = errno_save;
1920Sstevel@tonic-gate 	return (res);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate char *
dcngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n,int category)196*6812Sraf dcngettext(const char *domain, const char *msgid1, const char *msgid2,
1970Sstevel@tonic-gate 	unsigned long int n, int category)
1980Sstevel@tonic-gate {
1990Sstevel@tonic-gate 	char	*res;
2000Sstevel@tonic-gate 	int	errno_save = errno;
2010Sstevel@tonic-gate 
2025002Sraf 	callout_lock_enter();
2030Sstevel@tonic-gate 	INIT_GT((char *)msgid1);
2040Sstevel@tonic-gate 	res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1);
2055002Sraf 	callout_lock_exit();
2060Sstevel@tonic-gate 	errno = errno_save;
2070Sstevel@tonic-gate 	return (res);
2080Sstevel@tonic-gate }
209