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 /*
237257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
26*b599bd93SRobert Mustacchi /*
27*b599bd93SRobert Mustacchi * Copyright 2015 Joyent, Inc.
28*b599bd93SRobert Mustacchi */
297c478bd9Sstevel@tonic-gate
307257d1b4Sraf #pragma weak _bindtextdomain = bindtextdomain
317257d1b4Sraf #pragma weak _textdomain = textdomain
327257d1b4Sraf #pragma weak _gettext = gettext
337257d1b4Sraf #pragma weak _dgettext = dgettext
347257d1b4Sraf #pragma weak _dcgettext = dcgettext
357257d1b4Sraf #pragma weak _ngettext = ngettext
367257d1b4Sraf #pragma weak _dngettext = dngettext
377257d1b4Sraf #pragma weak _dcngettext = dcngettext
387257d1b4Sraf #pragma weak _bind_textdomain_codeset = bind_textdomain_codeset
397257d1b4Sraf
407257d1b4Sraf #include "lint.h"
417c478bd9Sstevel@tonic-gate #include "mtlib.h"
427c478bd9Sstevel@tonic-gate #include <errno.h>
437c478bd9Sstevel@tonic-gate #include <ctype.h>
447c478bd9Sstevel@tonic-gate #include <locale.h>
457c478bd9Sstevel@tonic-gate #include <stdio.h>
467c478bd9Sstevel@tonic-gate #include <stdlib.h>
477c478bd9Sstevel@tonic-gate #include <sys/types.h>
487c478bd9Sstevel@tonic-gate #include <sys/param.h>
497c478bd9Sstevel@tonic-gate #include <libintl.h>
507c478bd9Sstevel@tonic-gate #include <thread.h>
517c478bd9Sstevel@tonic-gate #include <synch.h>
527c478bd9Sstevel@tonic-gate #include "libc.h"
537c478bd9Sstevel@tonic-gate #include "_loc_path.h"
547c478bd9Sstevel@tonic-gate #include "msgfmt.h"
557c478bd9Sstevel@tonic-gate #include "gettext.h"
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate #define INIT_GT(def) \
587c478bd9Sstevel@tonic-gate if (!global_gt) { \
597c478bd9Sstevel@tonic-gate global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \
607c478bd9Sstevel@tonic-gate if (global_gt) \
617c478bd9Sstevel@tonic-gate global_gt->cur_domain = (char *)default_domain; \
627c478bd9Sstevel@tonic-gate else { \
6398c1a6b4Sraf callout_lock_exit(); \
647c478bd9Sstevel@tonic-gate return ((def)); \
657c478bd9Sstevel@tonic-gate } \
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate const char *defaultbind = DEFAULT_BINDING;
697c478bd9Sstevel@tonic-gate const char default_domain[] = DEFAULT_DOMAIN;
707c478bd9Sstevel@tonic-gate Gettext_t *global_gt = NULL;
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate char *
bindtextdomain(const char * domain,const char * binding)737257d1b4Sraf bindtextdomain(const char *domain, const char *binding)
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate char *res;
767c478bd9Sstevel@tonic-gate
7798c1a6b4Sraf callout_lock_enter();
787c478bd9Sstevel@tonic-gate INIT_GT(NULL);
797c478bd9Sstevel@tonic-gate res = _real_bindtextdomain_u(domain, binding, TP_BINDING);
8098c1a6b4Sraf callout_lock_exit();
817c478bd9Sstevel@tonic-gate return (res);
827c478bd9Sstevel@tonic-gate }
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate char *
bind_textdomain_codeset(const char * domain,const char * codeset)857257d1b4Sraf bind_textdomain_codeset(const char *domain, const char *codeset)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate char *res;
887c478bd9Sstevel@tonic-gate
8998c1a6b4Sraf callout_lock_enter();
907c478bd9Sstevel@tonic-gate INIT_GT(NULL);
917c478bd9Sstevel@tonic-gate res = _real_bindtextdomain_u(domain, codeset, TP_CODESET);
9298c1a6b4Sraf callout_lock_exit();
937c478bd9Sstevel@tonic-gate return (res);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate * textdomain() sets or queries the name of the current domain of
987c478bd9Sstevel@tonic-gate * the active LC_MESSAGES locale category.
997c478bd9Sstevel@tonic-gate */
1007c478bd9Sstevel@tonic-gate char *
textdomain(const char * domain)1017257d1b4Sraf textdomain(const char *domain)
1027c478bd9Sstevel@tonic-gate {
1037c478bd9Sstevel@tonic-gate char *res;
1047c478bd9Sstevel@tonic-gate char tmp_domain[TEXTDOMAINMAX + 1];
1057c478bd9Sstevel@tonic-gate
10698c1a6b4Sraf callout_lock_enter();
1077c478bd9Sstevel@tonic-gate INIT_GT(NULL);
1087c478bd9Sstevel@tonic-gate res = _textdomain_u(domain, tmp_domain);
1097c478bd9Sstevel@tonic-gate if (res == NULL) {
11098c1a6b4Sraf callout_lock_exit();
1117c478bd9Sstevel@tonic-gate return (NULL);
1127c478bd9Sstevel@tonic-gate }
11398c1a6b4Sraf callout_lock_exit();
1147c478bd9Sstevel@tonic-gate return (CURRENT_DOMAIN(global_gt));
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate /*
1187c478bd9Sstevel@tonic-gate * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed
1197c478bd9Sstevel@tonic-gate * for domain and LC_MESSAGES passed for category.
1207c478bd9Sstevel@tonic-gate */
1217c478bd9Sstevel@tonic-gate char *
gettext(const char * msg_id)1227257d1b4Sraf gettext(const char *msg_id)
1237c478bd9Sstevel@tonic-gate {
1247c478bd9Sstevel@tonic-gate char *res;
1257c478bd9Sstevel@tonic-gate int errno_save = errno;
1267c478bd9Sstevel@tonic-gate
12798c1a6b4Sraf callout_lock_enter();
1287c478bd9Sstevel@tonic-gate INIT_GT((char *)msg_id);
129*b599bd93SRobert Mustacchi res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0, NULL);
13098c1a6b4Sraf callout_lock_exit();
1317c478bd9Sstevel@tonic-gate errno = errno_save;
1327c478bd9Sstevel@tonic-gate return (res);
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate /*
1377c478bd9Sstevel@tonic-gate * In dcgettext() call, domain is valid only for this call.
1387c478bd9Sstevel@tonic-gate */
1397c478bd9Sstevel@tonic-gate char *
dgettext(const char * domain,const char * msg_id)1407257d1b4Sraf dgettext(const char *domain, const char *msg_id)
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate char *res;
1437c478bd9Sstevel@tonic-gate int errno_save = errno;
1447c478bd9Sstevel@tonic-gate
14598c1a6b4Sraf callout_lock_enter();
1467c478bd9Sstevel@tonic-gate INIT_GT((char *)msg_id);
147*b599bd93SRobert Mustacchi res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0, NULL);
148*b599bd93SRobert Mustacchi callout_lock_exit();
149*b599bd93SRobert Mustacchi errno = errno_save;
150*b599bd93SRobert Mustacchi return (res);
151*b599bd93SRobert Mustacchi }
152*b599bd93SRobert Mustacchi
153*b599bd93SRobert Mustacchi char *
dgettext_l(const char * domain,const char * msg_id,locale_t loc)154*b599bd93SRobert Mustacchi dgettext_l(const char *domain, const char *msg_id, locale_t loc)
155*b599bd93SRobert Mustacchi {
156*b599bd93SRobert Mustacchi char *res;
157*b599bd93SRobert Mustacchi int errno_save = errno;
158*b599bd93SRobert Mustacchi
159*b599bd93SRobert Mustacchi callout_lock_enter();
160*b599bd93SRobert Mustacchi INIT_GT((char *)msg_id);
161*b599bd93SRobert Mustacchi res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0, loc);
16298c1a6b4Sraf callout_lock_exit();
1637c478bd9Sstevel@tonic-gate errno = errno_save;
1647c478bd9Sstevel@tonic-gate return (res);
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate char *
dcgettext(const char * domain,const char * msg_id,const int category)1687257d1b4Sraf dcgettext(const char *domain, const char *msg_id, const int category)
1697c478bd9Sstevel@tonic-gate {
1707c478bd9Sstevel@tonic-gate char *res;
1717c478bd9Sstevel@tonic-gate int errno_save = errno;
1727c478bd9Sstevel@tonic-gate
17398c1a6b4Sraf callout_lock_enter();
1747c478bd9Sstevel@tonic-gate INIT_GT((char *)msg_id);
175*b599bd93SRobert Mustacchi res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0, NULL);
17698c1a6b4Sraf callout_lock_exit();
1777c478bd9Sstevel@tonic-gate errno = errno_save;
1787c478bd9Sstevel@tonic-gate return (res);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate char *
ngettext(const char * msgid1,const char * msgid2,unsigned long int n)1827257d1b4Sraf ngettext(const char *msgid1, const char *msgid2, 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);
189*b599bd93SRobert Mustacchi res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1, NULL);
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 *
dngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n)1967257d1b4Sraf dngettext(const char *domain, const char *msgid1, const char *msgid2,
1977c478bd9Sstevel@tonic-gate unsigned long int n)
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);
204*b599bd93SRobert Mustacchi res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1, NULL);
20598c1a6b4Sraf callout_lock_exit();
2067c478bd9Sstevel@tonic-gate errno = errno_save;
2077c478bd9Sstevel@tonic-gate return (res);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate char *
dcngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n,int category)2117257d1b4Sraf dcngettext(const char *domain, const char *msgid1, const char *msgid2,
2127c478bd9Sstevel@tonic-gate unsigned long int n, int category)
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate char *res;
2157c478bd9Sstevel@tonic-gate int errno_save = errno;
2167c478bd9Sstevel@tonic-gate
21798c1a6b4Sraf callout_lock_enter();
2187c478bd9Sstevel@tonic-gate INIT_GT((char *)msgid1);
219*b599bd93SRobert Mustacchi res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1, NULL);
22098c1a6b4Sraf callout_lock_exit();
2217c478bd9Sstevel@tonic-gate errno = errno_save;
2227c478bd9Sstevel@tonic-gate return (res);
2237c478bd9Sstevel@tonic-gate }
224