17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52e145884Sraf * Common Development and Distribution License (the "License").
62e145884Sraf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
212e145884Sraf
227c478bd9Sstevel@tonic-gate /*
23*7257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
287c478bd9Sstevel@tonic-gate
29*7257d1b4Sraf #pragma weak _bindtextdomain = bindtextdomain
30*7257d1b4Sraf #pragma weak _textdomain = textdomain
31*7257d1b4Sraf #pragma weak _gettext = gettext
32*7257d1b4Sraf #pragma weak _dgettext = dgettext
33*7257d1b4Sraf #pragma weak _dcgettext = dcgettext
34*7257d1b4Sraf #pragma weak _ngettext = ngettext
35*7257d1b4Sraf #pragma weak _dngettext = dngettext
36*7257d1b4Sraf #pragma weak _dcngettext = dcngettext
37*7257d1b4Sraf #pragma weak _bind_textdomain_codeset = bind_textdomain_codeset
387c478bd9Sstevel@tonic-gate
39*7257d1b4Sraf #include "lint.h"
407c478bd9Sstevel@tonic-gate #include "mtlib.h"
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <ctype.h>
437c478bd9Sstevel@tonic-gate #include <locale.h>
447c478bd9Sstevel@tonic-gate #include <stdio.h>
457c478bd9Sstevel@tonic-gate #include <stdlib.h>
467c478bd9Sstevel@tonic-gate #include <sys/types.h>
477c478bd9Sstevel@tonic-gate #include <sys/param.h>
487c478bd9Sstevel@tonic-gate #include <libintl.h>
497c478bd9Sstevel@tonic-gate #include <thread.h>
507c478bd9Sstevel@tonic-gate #include <synch.h>
517c478bd9Sstevel@tonic-gate #include "libc.h"
527c478bd9Sstevel@tonic-gate #include "_loc_path.h"
537c478bd9Sstevel@tonic-gate #include "msgfmt.h"
547c478bd9Sstevel@tonic-gate #include "gettext.h"
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #define INIT_GT(def) \
577c478bd9Sstevel@tonic-gate if (!global_gt) { \
587c478bd9Sstevel@tonic-gate global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \
597c478bd9Sstevel@tonic-gate if (global_gt) \
607c478bd9Sstevel@tonic-gate global_gt->cur_domain = (char *)default_domain; \
617c478bd9Sstevel@tonic-gate else { \
6298c1a6b4Sraf callout_lock_exit(); \
637c478bd9Sstevel@tonic-gate return ((def)); \
647c478bd9Sstevel@tonic-gate } \
657c478bd9Sstevel@tonic-gate }
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate const char *defaultbind = DEFAULT_BINDING;
687c478bd9Sstevel@tonic-gate const char default_domain[] = DEFAULT_DOMAIN;
697c478bd9Sstevel@tonic-gate Gettext_t *global_gt = NULL;
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate char *
bindtextdomain(const char * domain,const char * binding)72*7257d1b4Sraf bindtextdomain(const char *domain, const char *binding)
737c478bd9Sstevel@tonic-gate {
747c478bd9Sstevel@tonic-gate char *res;
757c478bd9Sstevel@tonic-gate
7698c1a6b4Sraf callout_lock_enter();
777c478bd9Sstevel@tonic-gate INIT_GT(NULL);
787c478bd9Sstevel@tonic-gate res = _real_bindtextdomain_u(domain, binding, TP_BINDING);
7998c1a6b4Sraf callout_lock_exit();
807c478bd9Sstevel@tonic-gate return (res);
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate char *
bind_textdomain_codeset(const char * domain,const char * codeset)84*7257d1b4Sraf bind_textdomain_codeset(const char *domain, const char *codeset)
857c478bd9Sstevel@tonic-gate {
867c478bd9Sstevel@tonic-gate char *res;
877c478bd9Sstevel@tonic-gate
8898c1a6b4Sraf callout_lock_enter();
897c478bd9Sstevel@tonic-gate INIT_GT(NULL);
907c478bd9Sstevel@tonic-gate res = _real_bindtextdomain_u(domain, codeset, TP_CODESET);
9198c1a6b4Sraf callout_lock_exit();
927c478bd9Sstevel@tonic-gate return (res);
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate * textdomain() sets or queries the name of the current domain of
977c478bd9Sstevel@tonic-gate * the active LC_MESSAGES locale category.
987c478bd9Sstevel@tonic-gate */
997c478bd9Sstevel@tonic-gate char *
textdomain(const char * domain)100*7257d1b4Sraf textdomain(const char *domain)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate char *res;
1037c478bd9Sstevel@tonic-gate char tmp_domain[TEXTDOMAINMAX + 1];
1047c478bd9Sstevel@tonic-gate
10598c1a6b4Sraf callout_lock_enter();
1067c478bd9Sstevel@tonic-gate INIT_GT(NULL);
1077c478bd9Sstevel@tonic-gate res = _textdomain_u(domain, tmp_domain);
1087c478bd9Sstevel@tonic-gate if (res == NULL) {
10998c1a6b4Sraf callout_lock_exit();
1107c478bd9Sstevel@tonic-gate return (NULL);
1117c478bd9Sstevel@tonic-gate }
11298c1a6b4Sraf callout_lock_exit();
1137c478bd9Sstevel@tonic-gate return (CURRENT_DOMAIN(global_gt));
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate /*
1177c478bd9Sstevel@tonic-gate * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed
1187c478bd9Sstevel@tonic-gate * for domain and LC_MESSAGES passed for category.
1197c478bd9Sstevel@tonic-gate */
1207c478bd9Sstevel@tonic-gate char *
gettext(const char * msg_id)121*7257d1b4Sraf gettext(const char *msg_id)
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate char *res;
1247c478bd9Sstevel@tonic-gate int errno_save = errno;
1257c478bd9Sstevel@tonic-gate
12698c1a6b4Sraf callout_lock_enter();
1277c478bd9Sstevel@tonic-gate INIT_GT((char *)msg_id);
1287c478bd9Sstevel@tonic-gate res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0);
12998c1a6b4Sraf callout_lock_exit();
1307c478bd9Sstevel@tonic-gate errno = errno_save;
1317c478bd9Sstevel@tonic-gate return (res);
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate * In dcgettext() call, domain is valid only for this call.
1377c478bd9Sstevel@tonic-gate */
1387c478bd9Sstevel@tonic-gate char *
dgettext(const char * domain,const char * msg_id)139*7257d1b4Sraf dgettext(const char *domain, const char *msg_id)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate char *res;
1427c478bd9Sstevel@tonic-gate int errno_save = errno;
1437c478bd9Sstevel@tonic-gate
14498c1a6b4Sraf callout_lock_enter();
1457c478bd9Sstevel@tonic-gate INIT_GT((char *)msg_id);
1467c478bd9Sstevel@tonic-gate res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0);
14798c1a6b4Sraf callout_lock_exit();
1487c478bd9Sstevel@tonic-gate errno = errno_save;
1497c478bd9Sstevel@tonic-gate return (res);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate char *
dcgettext(const char * domain,const char * msg_id,const int category)153*7257d1b4Sraf dcgettext(const char *domain, const char *msg_id, const int category)
1547c478bd9Sstevel@tonic-gate {
1557c478bd9Sstevel@tonic-gate char *res;
1567c478bd9Sstevel@tonic-gate int errno_save = errno;
1577c478bd9Sstevel@tonic-gate
15898c1a6b4Sraf callout_lock_enter();
1597c478bd9Sstevel@tonic-gate INIT_GT((char *)msg_id);
1607c478bd9Sstevel@tonic-gate res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0);
16198c1a6b4Sraf callout_lock_exit();
1627c478bd9Sstevel@tonic-gate errno = errno_save;
1637c478bd9Sstevel@tonic-gate return (res);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate char *
ngettext(const char * msgid1,const char * msgid2,unsigned long int n)167*7257d1b4Sraf ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate char *res;
1707c478bd9Sstevel@tonic-gate int errno_save = errno;
1717c478bd9Sstevel@tonic-gate
17298c1a6b4Sraf callout_lock_enter();
1737c478bd9Sstevel@tonic-gate INIT_GT((char *)msgid1);
1747c478bd9Sstevel@tonic-gate res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1);
17598c1a6b4Sraf callout_lock_exit();
1767c478bd9Sstevel@tonic-gate errno = errno_save;
1777c478bd9Sstevel@tonic-gate return (res);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate char *
dngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n)181*7257d1b4Sraf dngettext(const char *domain, const char *msgid1, const char *msgid2,
1827c478bd9Sstevel@tonic-gate unsigned long int n)
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate char *res;
1857c478bd9Sstevel@tonic-gate int errno_save = errno;
1867c478bd9Sstevel@tonic-gate
18798c1a6b4Sraf callout_lock_enter();
1887c478bd9Sstevel@tonic-gate INIT_GT((char *)msgid1);
1897c478bd9Sstevel@tonic-gate res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1);
19098c1a6b4Sraf callout_lock_exit();
1917c478bd9Sstevel@tonic-gate errno = errno_save;
1927c478bd9Sstevel@tonic-gate return (res);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate char *
dcngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n,int category)196*7257d1b4Sraf dcngettext(const char *domain, const char *msgid1, const char *msgid2,
1977c478bd9Sstevel@tonic-gate unsigned long int n, int category)
1987c478bd9Sstevel@tonic-gate {
1997c478bd9Sstevel@tonic-gate char *res;
2007c478bd9Sstevel@tonic-gate int errno_save = errno;
2017c478bd9Sstevel@tonic-gate
20298c1a6b4Sraf callout_lock_enter();
2037c478bd9Sstevel@tonic-gate INIT_GT((char *)msgid1);
2047c478bd9Sstevel@tonic-gate res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1);
20598c1a6b4Sraf callout_lock_exit();
2067c478bd9Sstevel@tonic-gate errno = errno_save;
2077c478bd9Sstevel@tonic-gate return (res);
2087c478bd9Sstevel@tonic-gate }
209