2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#pragma weak _bindtextdomain = bindtextdomain
2N/A#pragma weak _textdomain = textdomain
2N/A#pragma weak _gettext = gettext
2N/A#pragma weak _dgettext = dgettext
2N/A#pragma weak _dcgettext = dcgettext
2N/A#pragma weak _ngettext = ngettext
2N/A#pragma weak _dngettext = dngettext
2N/A#pragma weak _dcngettext = dcngettext
2N/A#pragma weak _bind_textdomain_codeset = bind_textdomain_codeset
2N/A
2N/A#include "lint.h"
2N/A#include "mtlib.h"
2N/A#include <errno.h>
2N/A#include <ctype.h>
2N/A#include <locale.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <sys/types.h>
2N/A#include <sys/param.h>
2N/A#include <libintl.h>
2N/A#include <thread.h>
2N/A#include <synch.h>
2N/A#include "libc.h"
2N/A#include "_loc_path.h"
2N/A#include "msgfmt.h"
2N/A#include "gettext.h"
2N/A
2N/A#define INIT_GT(def) \
2N/A if (!global_gt) { \
2N/A global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \
2N/A if (global_gt) \
2N/A global_gt->cur_domain = (char *)default_domain; \
2N/A else { \
2N/A callout_lock_exit(); \
2N/A return ((def)); \
2N/A } \
2N/A }
2N/A
2N/Aconst char *defaultbind = DEFAULT_BINDING;
2N/Aconst char default_domain[] = DEFAULT_DOMAIN;
2N/AGettext_t *global_gt = NULL;
2N/A
2N/Achar *
2N/Abindtextdomain(const char *domain, const char *binding)
2N/A{
2N/A char *res;
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT(NULL);
2N/A res = _real_bindtextdomain_u(domain, binding, TP_BINDING);
2N/A callout_lock_exit();
2N/A return (res);
2N/A}
2N/A
2N/Achar *
2N/Abind_textdomain_codeset(const char *domain, const char *codeset)
2N/A{
2N/A char *res;
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT(NULL);
2N/A res = _real_bindtextdomain_u(domain, codeset, TP_CODESET);
2N/A callout_lock_exit();
2N/A return (res);
2N/A}
2N/A
2N/A/*
2N/A * textdomain() sets or queries the name of the current domain of
2N/A * the active LC_MESSAGES locale category.
2N/A */
2N/Achar *
2N/Atextdomain(const char *domain)
2N/A{
2N/A char *res;
2N/A char tmp_domain[TEXTDOMAINMAX + 1];
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT(NULL);
2N/A res = _textdomain_u(domain, tmp_domain);
2N/A if (res == NULL) {
2N/A callout_lock_exit();
2N/A return (NULL);
2N/A }
2N/A callout_lock_exit();
2N/A return (CURRENT_DOMAIN(global_gt));
2N/A}
2N/A
2N/A/*
2N/A * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed
2N/A * for domain and LC_MESSAGES passed for category.
2N/A */
2N/Achar *
2N/Agettext(const char *msg_id)
2N/A{
2N/A char *res;
2N/A int errno_save = errno;
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT((char *)msg_id);
2N/A res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0);
2N/A callout_lock_exit();
2N/A errno = errno_save;
2N/A return (res);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * In dcgettext() call, domain is valid only for this call.
2N/A */
2N/Achar *
2N/Adgettext(const char *domain, const char *msg_id)
2N/A{
2N/A char *res;
2N/A int errno_save = errno;
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT((char *)msg_id);
2N/A res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0);
2N/A callout_lock_exit();
2N/A errno = errno_save;
2N/A return (res);
2N/A}
2N/A
2N/Achar *
2N/Adcgettext(const char *domain, const char *msg_id, const int category)
2N/A{
2N/A char *res;
2N/A int errno_save = errno;
2N/A
2N/A if (category < LC_CTYPE || category > _LastCategory)
2N/A return ((char *)msg_id);
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT((char *)msg_id);
2N/A res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0);
2N/A callout_lock_exit();
2N/A errno = errno_save;
2N/A return (res);
2N/A}
2N/A
2N/Achar *
2N/Angettext(const char *msgid1, const char *msgid2, unsigned long int n)
2N/A{
2N/A char *res;
2N/A int errno_save = errno;
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT((char *)msgid1);
2N/A res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1);
2N/A callout_lock_exit();
2N/A errno = errno_save;
2N/A return (res);
2N/A}
2N/A
2N/Achar *
2N/Adngettext(const char *domain, const char *msgid1, const char *msgid2,
2N/A unsigned long int n)
2N/A{
2N/A char *res;
2N/A int errno_save = errno;
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT((char *)msgid1);
2N/A res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1);
2N/A callout_lock_exit();
2N/A errno = errno_save;
2N/A return (res);
2N/A}
2N/A
2N/Achar *
2N/Adcngettext(const char *domain, const char *msgid1, const char *msgid2,
2N/A unsigned long int n, int category)
2N/A{
2N/A char *res;
2N/A int errno_save = errno;
2N/A
2N/A if (category < LC_CTYPE || category > _LastCategory)
2N/A return ((n == 1) ? (char *)msgid1 : (char *)msgid2);
2N/A
2N/A callout_lock_enter();
2N/A INIT_GT((char *)msgid1);
2N/A res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1);
2N/A callout_lock_exit();
2N/A errno = errno_save;
2N/A return (res);
2N/A}