gettext.c revision 2e14588420ccfbaa5be20605ed2be8b9802d1d49
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie/*
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * CDDL HEADER START
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * The contents of this file are subject to the terms of the
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * Common Development and Distribution License (the "License").
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * You may not use this file except in compliance with the License.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * or http://www.opensolaris.org/os/licensing.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * See the License for the specific language governing permissions
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * and limitations under the License.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * When distributing Covered Code, include this CDDL HEADER in each
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * If applicable, add the following below this CDDL HEADER, with the
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * fields enclosed by brackets "[]" replaced with your own identifying
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * information: Portions Copyright [yyyy] [name of copyright owner]
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * CDDL HEADER END
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie */
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie/*
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * Use is subject to license terms.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie */
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma ident "%Z%%M% %I% %E% SMI"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak bindtextdomain = _bindtextdomain
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak textdomain = _textdomain
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak gettext = _gettext
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak dgettext = _dgettext
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak dcgettext = _dcgettext
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak ngettext = _ngettext
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak dngettext = _dngettext
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak dcngettext = _dcngettext
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#pragma weak bind_textdomain_codeset = _bind_textdomain_codeset
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include "synonyms.h"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include "mtlib.h"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <errno.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <ctype.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <locale.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <stdio.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <stdlib.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <sys/types.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <sys/param.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <libintl.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <thread.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include <synch.h>
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include "libc.h"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include "_loc_path.h"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include "msgfmt.h"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#include "gettext.h"
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie#define INIT_GT(def) \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie if (!global_gt) { \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie if (global_gt) \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie global_gt->cur_domain = (char *)default_domain; \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie else { \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit(); \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return ((def)); \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie } \
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie }
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arieconst char *defaultbind = DEFAULT_BINDING;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arieconst char default_domain[] = DEFAULT_DOMAIN;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arieGettext_t *global_gt = NULL;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_bindtextdomain(const char *domain, const char *binding)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT(NULL);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _real_bindtextdomain_u(domain, binding, TP_BINDING);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_bind_textdomain_codeset(const char *domain, const char *codeset)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT(NULL);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _real_bindtextdomain_u(domain, codeset, TP_CODESET);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie/*
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * textdomain() sets or queries the name of the current domain of
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * the active LC_MESSAGES locale category.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie */
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_textdomain(const char *domain)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char tmp_domain[TEXTDOMAINMAX + 1];
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT(NULL);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _textdomain_u(domain, tmp_domain);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie if (res == NULL) {
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (NULL);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie }
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (CURRENT_DOMAIN(global_gt));
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie/*
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * for domain and LC_MESSAGES passed for category.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie */
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_gettext(const char *msg_id)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie int errno_save = errno;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT((char *)msg_id);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie errno = errno_save;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie/*
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie * In dcgettext() call, domain is valid only for this call.
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie */
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_dgettext(const char *domain, const char *msg_id)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie int errno_save = errno;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT((char *)msg_id);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie errno = errno_save;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_dcgettext(const char *domain, const char *msg_id, const int category)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie int errno_save = errno;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT((char *)msg_id);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie errno = errno_save;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf_ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf{
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf char *res;
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf int errno_save = errno;
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf fork_lock_enter();
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf INIT_GT((char *)msgid1);
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1);
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf fork_lock_exit();
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf errno = errno_save;
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf return (res);
a574db851cdc636fc3939b68e80d79fe7fbd57f2raf}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_dngettext(const char *domain, const char *msgid1, const char *msgid2,
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie unsigned long int n)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie int errno_save = errno;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
8cd45542f2a452ca0dab13d8b2d5cfa876ccbebcraf fork_lock_enter();
8cd45542f2a452ca0dab13d8b2d5cfa876ccbebcraf INIT_GT((char *)msgid1);
8cd45542f2a452ca0dab13d8b2d5cfa876ccbebcraf res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie errno = errno_save;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661ariechar *
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie_dcngettext(const char *domain, const char *msgid1, const char *msgid2,
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie unsigned long int n, int category)
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie{
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie char *res;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie int errno_save = errno;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_enter();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie INIT_GT((char *)msgid1);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie fork_lock_exit();
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie errno = errno_save;
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie return (res);
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie}
10a4fa49f51ed9ae1c857a626de6ce9ebf41661arie