+2000-06-16 Ulrich Drepper <drepper@redhat.com>
+
+ * iconv/gconv_int.h (norm_add_slashes): Optionally add given suffix.
+ * iconv/gconv_open.c: Remove error handling specification from `from'
+ character set name.
+ * intl/loadmsgcat.c (_nl_load_domain): Call norm_add_slashes with
+ new parameter to always enable transliteration.
+ * locale/localeinfo.h (LIMAGIC): Bump number because of incompatible
+ change.
+ (struct locale_data): Add new members use_translit and options.
+ * locale/findlocale.c (_nl_find_locale): Set use_translit flag is
+ character set name contained modifier TRANSLIT.
+ * locale/loadlocale.c (_nl_load_locale): Initialize new use_translit
+ and options fields.
+ (_nl_unload_locale): Free options string if necessary.
+ * wcsmbs/wcsmbsload.c (__wcsmbs_load_conv): Enable translation if
+ the locale names suggested this.
+ * locale/C-address.c: Add two new initialilzers to adjust data
+ structure for new format.
+ * locale/C-collate.c: Likewise.
+ * locale/C-ctype.c: Likewise.
+ * locale/C-identification.c: Likewise.
+ * locale/C-measurement.c: Likewise.
+ * locale/C-messages.c: Likewise.
+ * locale/C-monetary.c: Likewise.
+ * locale/C-name.c: Likewise.
+ * locale/C-numeric.c: Likewise.
+ * locale/C-paper.c: Likewise.
+ * locale/C-telephone.c: Likewise.
+ * locale/C-time.c: Likewise.
+
+ * locale/setlocale.c: Add some more __builtin_expect.
+
2000-06-15 Ulrich Drepper <drepper@redhat.com>
* iconv/gconv.h (__gconv_fct): Change type of fifth parameter to
/* The gconv functions expects the name to be in upper case and complete,
including the trailing slashes if necessary. */
-#define norm_add_slashes(str) \
+#define norm_add_slashes(str,suffix) \
({ \
const char *cp = (str); \
char *result; \
char *tmp; \
size_t cnt = 0; \
+ size_t suffix_len = suffix == NULL ? 0 : strlen (suffix); \
\
while (*cp != '\0') \
if (*cp++ == '/') \
++cnt; \
\
- tmp = result = alloca (cp - (str) + 3); \
+ tmp = result = alloca (cp - (str) + 3 + suffix_len); \
cp = (str); \
while (*cp != '\0') \
*tmp++ = _toupper (*cp++); \
{ \
*tmp++ = '/'; \
if (cnt < 1) \
- *tmp++ = '/'; \
+ { \
+ *tmp++ = '/'; \
+ if (suffix != NULL) \
+ tmp = __mempcpy (tmp, suffix, suffix_len); \
+ } \
} \
*tmp = '\0'; \
result; \
int res;
int conv_flags = 0;
const char *errhand;
+ const char *ignore;
/* Find out whether any error handling method is specified. */
errhand = strchr (toset, '/');
errhand = strchr (errhand + 1, '/');
if (__builtin_expect (errhand != NULL, 1))
{
- if (errhand[1] == '\0')
+ if (*++errhand == '\0')
errhand = NULL;
else
{
flags = __GCONV_IGNORE_ERRORS;
- if (strcasecmp (errhand, "IGNORE") == 0)
+ if (__strcasecmp (errhand, "IGNORE") == 0)
{
/* Found it. This means we should ignore conversion errors. */
flags = __GCONV_IGNORE_ERRORS;
}
}
+ /* For the source character set we ignore the error handler specification.
+ XXX Is this really always the best? */
+ ignore = strchr (fromset, '/');
+ if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL
+ && *++ignore != '\0')
+ {
+ char *newfromset = (char *) alloca (ignore - fromset + 1);
+
+ newfromset[ignore - fromset] = '\0';
+ fromset = memcpy (newfromset, fromset, ignore - fromset);
+ }
+
res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags);
if (res == __GCONV_OK)
{
if (errhand != NULL)
{
/* Find the appropriate transliteration handling. */
- if (strcasecmp (errhand, "TRANSLIT") == 0)
+ if (__strcasecmp (errhand, "TRANSLIT") == 0)
{
/* It's the builtin transliteration handling. We only
suport for it working on the internal encoding. */
trans_fct = __gconv_transliterate;
/* No context, init, or end function. */
}
- else if (strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0)
+ else if (__strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0)
{
trans_init_fct = (__gconv_trans_init_fct) 1;
}
/* Now see whether we can use the transliteration module
for this step. */
for (n = 0; n < ncsnames; ++n)
- if (strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
+ if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
{
/* Match! Now try the initializer. */
if (trans_init_fct == NULL
/* Now see whether we can use the transliteration module
for this step. */
for (n = 0; n < ncsnames; ++n)
- if (strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
+ if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0)
{
/* Match! Now try the initializer. */
if (trans_init_fct == NULL
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, \
- &inptr, inend, &outbuf, \
+ &inptr, inend, &outptr, \
irreversible)); \
if (result != __GCONV_OK) \
break; \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, \
- &inptr, inend, &outbuf, \
+ &inptr, inend, &outptr, \
irreversible)); \
if (result != __GCONV_OK) \
break; \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, \
- &inptr, inend, &outbuf, \
+ &inptr, inend, &outptr, \
irreversible)); \
if (result != __GCONV_OK) \
break; \
result = DL_CALL_FCT \
(step_data->__trans.__trans_fct,\
(step, step_data, *inptrp, \
- &inptr, inend, &outbuf, \
+ &inptr, inend, &outptr, \
irreversible)); \
if (result != __GCONV_OK) \
break; \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, inend, \
- &outbuf, irreversible)); \
+ &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
{ \
result = DL_CALL_FCT (step_data->__trans.__trans_fct, \
(step, step_data, *inptrp, &inptr, \
- inend, &outbuf, irreversible)); \
+ inend, &outptr, irreversible)); \
if (result != __GCONV_OK) \
break; \
} \
}
# ifdef _LIBC
- outcharset = norm_add_slashes (outcharset);
- charset = norm_add_slashes (charset);
+ /* We always want to use transliteration. */
+ outcharset = norm_add_slashes (outcharset, "TRANSLIT");
+ charset = norm_add_slashes (charset, NULL);
if (__gconv_open (outcharset, charset, &domain->conv,
GCONV_AVOID_NOCONV)
!= __GCONV_OK)
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
12,
{
{ string: "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" },
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
18,
{
{ word: 0 },
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
62,
{
{ string: _nl_C_LC_CTYPE_class },
-/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+/* 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.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
15,
{
{ string: "ISO/IEC 14652 i18n FDCC-set" },
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
1,
{
{ string: "\1" }
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
4,
{
{ string: "^[yY]" },
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
45,
{
{ string: "" },
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
6,
{
{ string: "%p%t%g%t%m%t%f" },
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
5,
{
{ string: "." },
-/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+/* 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.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
2,
{
{ word: 297 },
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
4,
{
{ string: "+%c %a %l" },
-/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
_nl_C_name,
NULL, 0, 0, /* no file mapped */
UNDELETABLE,
+ 0,
+ NULL,
62,
{
{ string: "Sun" },
}
*name = (char *) ((struct locale_data *) locale_file->data)->name;
+ /* Determine whether the user wants transliteration or not. */
+ if ((modifier != NULL && __strcasecmp (modifier, "TRANSLIT") == 0)
+ || (special != NULL && __strcasecmp (special, "TRANSLIT") == 0))
+ ((struct locale_data *) locale_file->data)->use_translit = 1;
+
/* Increment the usage count. */
if (((struct locale_data *) locale_file->data)->usage_count
< MAX_USAGE_COUNT)
newdata->filesize = st.st_size;
newdata->mmaped = mmaped;
newdata->usage_count = 0;
+ newdata->use_translit = 0;
+ newdata->options = NULL;
newdata->nstrings = filedata->nstrings;
for (cnt = 0; cnt < newdata->nstrings; ++cnt)
{
#endif
free ((void *) locale->filedata);
+ if (locale->options != NULL)
+ free (locale->options);
+
free (locale);
}
/* Declarations for internal libc locale interfaces
- Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
#include <intl/loadinfo.h> /* For loaded_l10nfile definition. */
/* Magic number at the beginning of a locale data file for CATEGORY. */
-#define LIMAGIC(category) (0x980505 ^ (category))
+#define LIMAGIC(category) (0x20000616 ^ (category))
/* Two special weight constants for the collation data. */
#define IGNORE_CHAR 2
unsigned int usage_count; /* Counter for users. */
+ int use_translit; /* Nonzero if the mb*towv*() and wc*tomb()
+ functions should use transliteration. */
+ const char *options; /* Extra options from the locale name,
+ not used in the path to the locale data. */
+
unsigned int nstrings; /* Number of strings below. */
union locale_data_value
{
char *composite;
/* Sanity check for CATEGORY argument. */
- if (category < 0 || category >= __LC_LAST)
+ if (__builtin_expect (category, 0) < 0
+ || __builtin_expect (category, 0) >= __LC_LAST)
ERROR_RETURN;
/* Does user want name of current locale? */
if (category != LC_ALL)
newnames[category] = (char *) locale;
- if (strchr (locale, ';') != NULL)
+ if (__builtin_expect (strchr (locale, ';') != NULL, 0))
{
/* This is a composite name. Make a copy and split it up. */
char *np = strdupa (locale);
/* We should repeat the test since while we waited some other thread
might have run this function. */
- if (__wcsmbs_last_locale != new_category)
+ if (__builtin_expect (__wcsmbs_last_locale != new_category, 1))
{
if (new_category->name == _nl_C_name) /* Yes, pointer comparison. */
{
const char *complete_name;
struct __gconv_step *new_towc;
struct __gconv_step *new_tomb;
+ int use_translit;
/* Free the old conversions. */
__gconv_close_transform (__wcsmbs_gconv_fcts.tomb, 1);
/* Get name of charset of the locale. */
charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
+ /* Does the user want transliteration? */
+ use_translit = new_category->use_translit;
+
/* Normalize the name and add the slashes necessary for a
complete lookup. */
- complete_name = norm_add_slashes (charset_name);
+ complete_name = norm_add_slashes (charset_name,
+ use_translit ? "TRANSLIT" : NULL);
+ /* It is not necessary to use transliteration in this direction
+ since the internal character set is supposed to be able to
+ represent all others. */
new_towc = getfct ("INTERNAL", complete_name);
if (new_towc != NULL)
new_tomb = getfct (complete_name, "INTERNAL");