glibc/wcsmbs/wcsmbsload.c
Ulrich Drepper 17c389fc2b Update.
* libio/stdio.h: Make fseeko and ftello prototypes available is
	__USE_LARGEFILE.  Patch by Paul Eggert <eggert@twinsun.com>.

	* sysdeps/generic/dl-environ.c (unsetenv): Follow change to the
	real unsetenv implementation from 1999-07-29 [PR libc/1714].

2000-05-03  Bruno Haible  <haible@clisp.cons.org>

	* intl/dcigettext.c (dcigettext): Do the defaulting of 'domainname'
	before calling tfind.

2000-03-05  Jakub Jelinek  <jakub@redhat.com>

	* resolv/resolv.h (res_querydomain): Remove redefinition to
	__res_querydomain (reported by Owen Taylor <otaylor@redhat.com>).

2000-05-03  Ulrich Drepper  <drepper@redhat.com>

	* po/gl.po: Update from translation team.

	* manual/intro.texi (Program Basics): Change section title.
	* manual/process.texi: Fix reference.
	(Executing a File): Add reference exec in other section.
	* manual/signal.texi: Fix reference.
	* manual/startup.texi: Document syscall function.
	Patches by Bryan Henderson <bryanh@giraffe-data.com>.

2000-04-29  Bruno Haible  <haible@clisp.cons.org>

	* intl/libintl.h (bind_textdomain_codeset): New declaration.
	* intl/bindtextdom.c (set_binding_values): New function.
	(bindtextdomain): Call it.
	(bind_textdomain_codeset): New function.
	* intl/dcigettext.c (dcigettext): Pass binding to _nl_find_domain.
	(free_mem): Free each binding's codeset.
	* intl/gettextP.h (struct binding): Add codeset field.
	(_nl_find_domain): Add domainbinding argument.
	* intl/finddomain.c (_nl_find_domain): Add domainbinding argument.
	Pass it to _nl_make_l10nflist.
	* intl/loadinfo.h (struct loaded_l10nfile): Add domainbinding field.
	(_nl_make_l10nflist): Add domainbinding argument.
	* intl/l10nflist.c (_nl_make_l10nflist): Add domainbinding argument.
	* intl/loadmsgcat.c (_nl_load_domain): Look at the domainbinding's
	codeset when determining outcharset. If !_LIBC && HAVE_ICONV, call
	locale_charset().
	* manual/message.texi: New node "Charset conversion in gettext".

2000-04-30  Bruno Haible  <haible@clisp.cons.org>

	* catgets/open_catalog.c (__open_catalog): Use __builtin_expect where
	appropriate.  Handle possible __read error.

2000-04-29  Bruno Haible  <haible@clisp.cons.org>

	* intl/gettextP.h (__builtin_expect): Define as empty if not a
	compiler builtin.
	* intl/loadinfo.h (__builtin_expect): Likewise.
	* intl/dcigettext.c (dcigettext, _nl_find_msg): Use
	__builtin_expect where appropriate.
	* intl/loadmsgcat.c (_nl_load_domain): Likewise.
	* intl/localealias.c (extend_alias_table): Return an error indicator.
	(read_alias_file): Bail out if extend_alias_table fails.

2000-04-29  Bruno Haible  <haible@clisp.cons.org>

	* intl/loadmsgcat.c: Define _GNU_SOURCE as early as possible.
	* intl/localealias.c: Likewise.

2000-05-01  Bruno Haible  <haible@clisp.cons.org>

	* intl/loadmsgcat.c (_nl_load_domain): Initialize domain->conv_tab.
	Initialize domain->plural and domain->nplurals even if there is no
	nullentry.

2000-05-01  Bruno Haible  <haible@clisp.cons.org>

	* intl/dcigettext.c (_nl_find_msg): Terminate __gconv loop if return
	value is == __GCONV_OK or == __GCONV_EMPTY_INPUT, not != __GCONV_OK.
	In case of failure, goto converted.

2000-05-01  Bruno Haible  <haible@clisp.cons.org>

	* wcsmbs/wcsmbsload.c (norm_add_slashes): Move away.
	* iconv/gconv_int.h (norm_add_slashes): Move to here.
	* intl/loadmsgcat.c (_nl_load_domain): Normalize strings passed to
	__gconv_open.

2000-04-29  Bruno Haible  <haible@clisp.cons.org>

	* intl/dcigettext.c (transcmp): Compare the domains as well.
	(dcigettext): Call strlen (msgid1) after testing msgid1 against NULL,
	not before.
	* intl/loadmsgcat.c (_nl_load_domain): Deal with EINTR. Include
	<errno.h>.

2000-05-03  Ulrich Drepper  <drepper@redhat.com>
2000-05-04 02:46:54 +00:00

251 lines
6.7 KiB
C

/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <langinfo.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <locale/localeinfo.h>
#include <wcsmbsload.h>
#include <bits/libc-lock.h>
#include <iconv/gconv_int.h>
/* Last loaded locale for LC_CTYPE. We initialize for the C locale
which is enabled at startup. */
extern const struct locale_data _nl_C_LC_CTYPE;
const struct locale_data *__wcsmbs_last_locale = &_nl_C_LC_CTYPE;
/* These are the descriptions for the default conversion functions. */
static struct __gconv_step to_wc =
{
.__shlib_handle = NULL,
.__modname = NULL,
.__counter = INT_MAX,
.__from_name = "ANSI_X3.4-1968//",
.__to_name = "INTERNAL",
.__fct = __gconv_transform_ascii_internal,
.__init_fct = NULL,
.__end_fct = NULL,
.__min_needed_from = 1,
.__max_needed_from = 1,
.__min_needed_to = 4,
.__max_needed_to = 4,
.__stateful = 0,
.__data = NULL
};
static struct __gconv_step to_mb =
{
.__shlib_handle = NULL,
.__modname = NULL,
.__counter = INT_MAX,
.__from_name = "INTERNAL",
.__to_name = "ANSI_X3.4-1968//",
.__fct = __gconv_transform_internal_ascii,
.__init_fct = NULL,
.__end_fct = NULL,
.__min_needed_from = 4,
.__max_needed_from = 4,
.__min_needed_to = 1,
.__max_needed_to = 1,
.__stateful = 0,
.__data = NULL
};
/* For the default locale we only have to handle ANSI_X3.4-1968. */
struct gconv_fcts __wcsmbs_gconv_fcts =
{
.towc = &to_wc,
.tomb = &to_mb
};
static inline struct __gconv_step *
getfct (const char *to, const char *from)
{
size_t nsteps;
struct __gconv_step *result;
size_t nstateful;
size_t cnt;
if (__gconv_find_transform (to, from, &result, &nsteps, 0) != __GCONV_OK)
/* Loading the conversion step is not possible. */
return NULL;
/* Count the number of stateful conversions. Since we will only
have one 'mbstate_t' object available we can only deal with one
stateful conversion. */
nstateful = 0;
for (cnt = 0; cnt < nsteps; ++cnt)
if (result[cnt].__stateful)
++nstateful;
if (nstateful > 1)
{
/* We cannot handle this case. */
__gconv_close_transform (result, nsteps);
result = NULL;
}
return result;
}
/* Extract from the given locale name the character set portion. Since
only the XPG form of the name includes this information we don't have
to take care for the CEN form. */
#define extract_charset_name(str) \
({ \
const char *cp = str; \
char *result = NULL; \
\
cp += strcspn (cp, "@.+,"); \
if (*cp == '.') \
{ \
const char *endp = ++cp; \
while (*endp != '\0' && *endp != '@') \
++endp; \
if (endp != cp) \
result = strndupa (cp, endp - cp); \
} \
result; \
})
/* We must modify global data. */
__libc_lock_define_initialized (static, lock)
/* Load conversion functions for the currently selected locale. */
void
internal_function
__wcsmbs_load_conv (const struct locale_data *new_category)
{
/* Acquire the lock. */
__libc_lock_lock (lock);
/* We should repest the test since while we waited some other thread
might have run this function. */
if (__wcsmbs_last_locale != new_category)
{
if (new_category->name == _nl_C_name) /* Yes, pointer comparison. */
{
failed:
__wcsmbs_gconv_fcts.towc = &to_wc;
__wcsmbs_gconv_fcts.tomb = &to_mb;
}
else
{
/* We must find the real functions. */
const char *charset_name;
const char *complete_name;
struct __gconv_step *new_towc;
struct __gconv_step *new_tomb;
/* Free the old conversions. */
__gconv_close_transform (__wcsmbs_gconv_fcts.tomb, 1);
__gconv_close_transform (__wcsmbs_gconv_fcts.towc, 1);
/* Get name of charset of the locale. */
charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
/* Normalize the name and add the slashes necessary for a
complete lookup. */
complete_name = norm_add_slashes (charset_name);
new_towc = getfct ("INTERNAL", complete_name);
if (new_towc != NULL)
new_tomb = getfct (complete_name, "INTERNAL");
/* If any of the conversion functions is not available we don't
use any since this would mean we cannot convert back and
forth.*/
if (new_towc == NULL || new_tomb == NULL)
{
if (new_towc != NULL)
__gconv_close_transform (new_towc, 1);
goto failed;
}
__wcsmbs_gconv_fcts.tomb = new_tomb;
__wcsmbs_gconv_fcts.towc = new_towc;
}
/* Set last-used variable for current locale. */
__wcsmbs_last_locale = new_category;
}
__libc_lock_unlock (lock);
}
/* Clone the current conversion function set. */
void
internal_function
__wcsmbs_clone_conv (struct gconv_fcts *copy)
{
/* First make sure the function table is up-to-date. */
update_conversion_ptrs ();
/* Make sure the data structures remain the same until we are finished. */
__libc_lock_lock (lock);
/* Copy the data. */
*copy = __wcsmbs_gconv_fcts;
/* Now increment the usage counters. */
if (copy->towc->__shlib_handle != NULL)
++copy->towc->__counter;
if (copy->tomb->__shlib_handle != NULL)
++copy->tomb->__counter;
__libc_lock_unlock (lock);
}
/* Clone the current conversion function set. */
int
internal_function
__wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
{
copy->towc = getfct ("INTERNAL", name);
if (copy->towc != NULL)
{
copy->tomb = getfct (name, "INTERNAL");
if (copy->tomb == NULL)
__gconv_close_transform (copy->towc, 1);
}
if (copy->towc == NULL || copy->tomb == NULL)
return 1;
/* Now increment the usage counters. */
if (copy->towc->__shlib_handle != NULL)
++copy->towc->__counter;
if (copy->tomb->__shlib_handle != NULL)
++copy->tomb->__counter;
return 0;
}