Drop all unneeded gconv converters.
* implement wchar->multibyte & multibyte->wchar conversions, make those the default converters and drop all others (except for ascii)
This commit is contained in:
parent
99916f57cc
commit
2370b92e15
@ -18,104 +18,8 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
BUILTIN_ALIAS ("UCS4//", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("UCS-4//", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("UCS-4BE//", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("CSUCS4//", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("ISO-10646//", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("10646-1:1993//", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("10646-1:1993/UCS4/", "ISO-10646/UCS4/")
|
||||
BUILTIN_ALIAS ("OSF00010104//", "ISO-10646/UCS4/") /* level 1 */
|
||||
BUILTIN_ALIAS ("OSF00010105//", "ISO-10646/UCS4/") /* level 2 */
|
||||
BUILTIN_ALIAS ("OSF00010106//", "ISO-10646/UCS4/") /* level 3 */
|
||||
BUILTIN_TRANSFORMATION ("MULTIBYTE", "WCHAR", 1, "=multibyte->wchar",
|
||||
__gconv_transform_multibyte_wchar, NULL, 4, 4, 1, MB_LEN_MAX)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UCS4/", 1, "=INTERNAL->ucs4",
|
||||
__gconv_transform_internal_ucs4, NULL, 4, 4, 4, 4)
|
||||
BUILTIN_TRANSFORMATION ("ISO-10646/UCS4/", "INTERNAL", 1, "=ucs4->INTERNAL",
|
||||
__gconv_transform_ucs4_internal, NULL, 4, 4, 4, 4)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "UCS-4LE//", 1, "=INTERNAL->ucs4le",
|
||||
__gconv_transform_internal_ucs4le, NULL, 4, 4, 4, 4)
|
||||
BUILTIN_TRANSFORMATION ("UCS-4LE//", "INTERNAL", 1, "=ucs4le->INTERNAL",
|
||||
__gconv_transform_ucs4le_internal, NULL, 4, 4, 4, 4)
|
||||
|
||||
BUILTIN_ALIAS ("WCHAR_T//", "INTERNAL")
|
||||
|
||||
BUILTIN_ALIAS ("UTF8//", "ISO-10646/UTF8/")
|
||||
BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/")
|
||||
BUILTIN_ALIAS ("ISO-IR-193//", "ISO-10646/UTF8/")
|
||||
BUILTIN_ALIAS ("OSF05010001//", "ISO-10646/UTF8/")
|
||||
BUILTIN_ALIAS ("ISO-10646/UTF-8/", "ISO-10646/UTF8/")
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UTF8/", 1, "=INTERNAL->utf8",
|
||||
__gconv_transform_internal_utf8, NULL, 4, 4, 1, 6)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("ISO-10646/UTF8/", "INTERNAL", 1, "=utf8->INTERNAL",
|
||||
__gconv_transform_utf8_internal, __gconv_btwoc_ascii,
|
||||
1, 6, 4, 4)
|
||||
|
||||
BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
|
||||
BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
|
||||
BUILTIN_ALIAS ("OSF00010100//", "ISO-10646/UCS2/") /* level 1 */
|
||||
BUILTIN_ALIAS ("OSF00010101//", "ISO-10646/UCS2/") /* level 2 */
|
||||
BUILTIN_ALIAS ("OSF00010102//", "ISO-10646/UCS2/") /* level 3 */
|
||||
|
||||
BUILTIN_TRANSFORMATION ("ISO-10646/UCS2/", "INTERNAL", 1, "=ucs2->INTERNAL",
|
||||
__gconv_transform_ucs2_internal, NULL, 2, 2, 4, 4)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UCS2/", 1, "=INTERNAL->ucs2",
|
||||
__gconv_transform_internal_ucs2, NULL, 4, 4, 2, 2)
|
||||
|
||||
|
||||
BUILTIN_ALIAS ("ANSI_X3.4//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("ISO-IR-6//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("ANSI_X3.4-1986//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("ISO_646.IRV:1991//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("ASCII//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("ISO646-US//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("US-ASCII//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("US//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("IBM367//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("CP367//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("CSASCII//", "ANSI_X3.4-1968//")
|
||||
BUILTIN_ALIAS ("OSF00010020//", "ANSI_X3.4-1968//")
|
||||
|
||||
BUILTIN_TRANSFORMATION ("ANSI_X3.4-1968//", "INTERNAL", 1, "=ascii->INTERNAL",
|
||||
__gconv_transform_ascii_internal, __gconv_btwoc_ascii,
|
||||
4, 4, 1, 1)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "ANSI_X3.4-1968//", 1, "=INTERNAL->ascii",
|
||||
__gconv_transform_internal_ascii, NULL, 4, 4, 1, 1)
|
||||
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
BUILTIN_ALIAS ("UNICODEBIG//", "ISO-10646/UCS2/")
|
||||
BUILTIN_ALIAS ("UCS-2BE//", "ISO-10646/UCS2/")
|
||||
|
||||
BUILTIN_ALIAS ("UCS-2LE//", "UNICODELITTLE//")
|
||||
|
||||
BUILTIN_TRANSFORMATION ("UNICODELITTLE//", "INTERNAL", 1,
|
||||
"=ucs2reverse->INTERNAL",
|
||||
__gconv_transform_ucs2reverse_internal, NULL,
|
||||
2, 2, 4, 4)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "UNICODELITTLE//", 1,
|
||||
"=INTERNAL->ucs2reverse",
|
||||
__gconv_transform_internal_ucs2reverse, NULL,
|
||||
4, 4, 2, 2)
|
||||
#else
|
||||
BUILTIN_ALIAS ("UNICODELITTLE//", "ISO-10646/UCS2/")
|
||||
BUILTIN_ALIAS ("UCS-2LE//", "ISO-10646/UCS2/")
|
||||
|
||||
BUILTIN_ALIAS ("UCS-2BE//", "UNICODEBIG//")
|
||||
|
||||
BUILTIN_TRANSFORMATION ("UNICODEBIG//", "INTERNAL", 1,
|
||||
"=ucs2reverse->INTERNAL",
|
||||
__gconv_transform_ucs2reverse_internal, NULL,
|
||||
2, 2, 4, 4)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("INTERNAL", "UNICODEBIG//", 1,
|
||||
"=INTERNAL->ucs2reverse",
|
||||
__gconv_transform_internal_ucs2reverse, NULL,
|
||||
4, 4, 2, 2)
|
||||
#endif
|
||||
BUILTIN_TRANSFORMATION ("WCHAR", "MULTIBYTE", 1, "=wchar->multibyte",
|
||||
__gconv_transform_wchar_multibyte, NULL, 4, 4, 1, MB_LEN_MAX)
|
||||
|
@ -272,26 +272,10 @@ extern int __gconv_transliterate (struct __gconv_step *step,
|
||||
unsigned char **outbufstart, size_t *irreversible, \
|
||||
int do_flush, int consume_incomplete)
|
||||
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_ascii_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_ascii);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_utf8_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_utf8);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_ucs2_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_ucs2reverse_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2reverse);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_ucs4_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4le);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_ucs4le_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_internal_utf16);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_utf16_internal);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_multibyte_wchar);
|
||||
__BUILTIN_TRANSFORM (__gconv_transform_wchar_multibyte);
|
||||
# undef __BUITLIN_TRANSFORM
|
||||
|
||||
/* Specialized conversion function for a single byte to INTERNAL, recognizing
|
||||
only ASCII characters. */
|
||||
extern wint_t __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c);
|
||||
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,37 +17,26 @@
|
||||
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 = (char *) "ANSI_X3.4-1968//TRANSLIT",
|
||||
.__to_name = (char *) "INTERNAL",
|
||||
.__fct = __gconv_transform_ascii_internal,
|
||||
.__from_name = (char *) "MULTIBYTE",
|
||||
.__to_name = (char *) "WCHAR",
|
||||
.__fct = __gconv_transform_multibyte_wchar,
|
||||
.__init_fct = NULL,
|
||||
.__end_fct = NULL,
|
||||
.__min_needed_from = 1,
|
||||
.__max_needed_from = 1,
|
||||
.__max_needed_from = MB_LEN_MAX,
|
||||
.__min_needed_to = 4,
|
||||
.__max_needed_to = 4,
|
||||
.__stateful = 0,
|
||||
@ -59,15 +48,15 @@ static struct __gconv_step to_mb =
|
||||
.__shlib_handle = NULL,
|
||||
.__modname = NULL,
|
||||
.__counter = INT_MAX,
|
||||
.__from_name = (char *) "INTERNAL",
|
||||
.__to_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
|
||||
.__fct = __gconv_transform_internal_ascii,
|
||||
.__from_name = (char *) "WCHAR",
|
||||
.__to_name = (char *) "MULTIBYTE",
|
||||
.__fct = __gconv_transform_wchar_multibyte,
|
||||
.__init_fct = NULL,
|
||||
.__end_fct = NULL,
|
||||
.__min_needed_from = 4,
|
||||
.__max_needed_from = 4,
|
||||
.__min_needed_to = 1,
|
||||
.__max_needed_to = 1,
|
||||
.__max_needed_to = MB_LEN_MAX,
|
||||
.__stateful = 0,
|
||||
.__data = NULL
|
||||
};
|
||||
@ -83,219 +72,11 @@ struct gconv_fcts __wcsmbs_gconv_fcts =
|
||||
};
|
||||
|
||||
|
||||
static inline struct __gconv_step *
|
||||
getfct (const char *to, const char *from, size_t *nstepsp)
|
||||
{
|
||||
size_t nsteps;
|
||||
struct __gconv_step *result;
|
||||
#if 0
|
||||
size_t nstateful;
|
||||
size_t cnt;
|
||||
#endif
|
||||
|
||||
if (__gconv_find_transform (to, from, &result, &nsteps, 0) != __GCONV_OK)
|
||||
/* Loading the conversion step is not possible. */
|
||||
return NULL;
|
||||
|
||||
/* Maybe it is someday necessary to allow more than one step.
|
||||
Currently this is not the case since the conversions handled here
|
||||
are from and to INTERNAL and there always is a converted for
|
||||
that. It the directly following code is enabled the libio
|
||||
functions will have to allocate appropriate __gconv_step_data
|
||||
elements instead of only one. */
|
||||
#if 0
|
||||
/* 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)
|
||||
#else
|
||||
if (nsteps > 1)
|
||||
#endif
|
||||
{
|
||||
/* We cannot handle this case. */
|
||||
__gconv_close_transform (result, nsteps);
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
*nstepsp = nsteps;
|
||||
|
||||
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 repeat the test since while we waited some other thread
|
||||
might have run this function. */
|
||||
if (__builtin_expect (__wcsmbs_last_locale != new_category, 1))
|
||||
{
|
||||
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;
|
||||
size_t new_towc_nsteps;
|
||||
struct __gconv_step *new_tomb;
|
||||
size_t new_tomb_nsteps;
|
||||
int use_translit;
|
||||
|
||||
/* Free the old conversions. */
|
||||
if (__wcsmbs_gconv_fcts.tomb != &to_mb)
|
||||
__gconv_close_transform (__wcsmbs_gconv_fcts.tomb,
|
||||
__wcsmbs_gconv_fcts.tomb_nsteps);
|
||||
if (__wcsmbs_gconv_fcts.towc != &to_wc)
|
||||
__gconv_close_transform (__wcsmbs_gconv_fcts.towc,
|
||||
__wcsmbs_gconv_fcts.towc_nsteps);
|
||||
|
||||
/* 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,
|
||||
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, &new_towc_nsteps);
|
||||
new_tomb = (new_towc != NULL
|
||||
? getfct (complete_name, "INTERNAL", &new_tomb_nsteps)
|
||||
: NULL);
|
||||
|
||||
/* 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.tomb_nsteps = new_tomb_nsteps;
|
||||
__wcsmbs_gconv_fcts.towc = new_towc;
|
||||
__wcsmbs_gconv_fcts.towc_nsteps = new_towc_nsteps;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
/* Get converters for named charset. */
|
||||
int
|
||||
internal_function
|
||||
__wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
|
||||
{
|
||||
copy->towc = getfct ("INTERNAL", name, ©->towc_nsteps);
|
||||
if (copy->towc != NULL)
|
||||
{
|
||||
copy->tomb = getfct (name, "INTERNAL", ©->tomb_nsteps);
|
||||
if (copy->tomb == NULL)
|
||||
__gconv_close_transform (copy->towc, copy->towc_nsteps);
|
||||
}
|
||||
|
||||
return copy->towc == NULL || copy->tomb == NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free all resources if necessary. */
|
||||
static void __attribute__ ((unused))
|
||||
free_mem (void)
|
||||
{
|
||||
if (__wcsmbs_gconv_fcts.tomb != &to_mb)
|
||||
{
|
||||
struct __gconv_step *old = __wcsmbs_gconv_fcts.tomb;
|
||||
size_t nold = __wcsmbs_gconv_fcts.tomb_nsteps;
|
||||
__wcsmbs_gconv_fcts.tomb = &to_mb;
|
||||
__wcsmbs_gconv_fcts.tomb_nsteps = 1;
|
||||
__gconv_release_cache (old, nold);
|
||||
}
|
||||
|
||||
if (__wcsmbs_gconv_fcts.towc != &to_wc)
|
||||
{
|
||||
struct __gconv_step *old = __wcsmbs_gconv_fcts.towc;
|
||||
size_t nold = __wcsmbs_gconv_fcts.towc_nsteps;
|
||||
__wcsmbs_gconv_fcts.towc = &to_wc;
|
||||
__wcsmbs_gconv_fcts.towc_nsteps = 1;
|
||||
__gconv_release_cache (old, nold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
text_set_element (__libc_subfreeres, free_mem);
|
||||
|
@ -35,28 +35,6 @@ struct gconv_fcts
|
||||
extern struct gconv_fcts __wcsmbs_gconv_fcts;
|
||||
|
||||
|
||||
/* Last loaded locale for LC_CTYPE. */
|
||||
extern const struct locale_data *__wcsmbs_last_locale;
|
||||
|
||||
|
||||
/* Load conversion functions for the currently selected locale. */
|
||||
extern void __wcsmbs_load_conv (const struct locale_data *new_category)
|
||||
internal_function;
|
||||
|
||||
/* Clone the current `__wcsmbs_load_conv' value. */
|
||||
extern void __wcsmbs_clone_conv (struct gconv_fcts *copy)
|
||||
internal_function;
|
||||
|
||||
/* Find the conversion functions for converting to and from NAME. */
|
||||
extern int __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
|
||||
internal_function;
|
||||
|
||||
|
||||
/* Check whether the LC_CTYPE locale changed since the last call.
|
||||
Update the pointers appropriately. */
|
||||
static inline void
|
||||
update_conversion_ptrs (void)
|
||||
{
|
||||
if (__wcsmbs_last_locale != _nl_current_LC_CTYPE)
|
||||
__wcsmbs_load_conv (_nl_current_LC_CTYPE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user