diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2000-06-16 00:39:38 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2000-06-16 00:39:38 +0000 |
| commit | f1d5c60ddef851078544e6b8456b18534b9a2a95 (patch) | |
| tree | e75b7ab28ae1b6b8276d663556ddda7eb640ce5d | |
| parent | f5361098c526e43f0437a491ed48122794b35451 (diff) | |
| download | glibc-f1d5c60ddef851078544e6b8456b18534b9a2a95.tar.xz glibc-f1d5c60ddef851078544e6b8456b18534b9a2a95.zip | |
Update.
2000-06-15 Ulrich Drepper <drepper@redhat.com>
* iconv/gconv.h (__gconv_fct): Change type of fifth parameter to
unsigned char **.
(__gconv_init_fct): Remove two parameters.
* iconv/gconv_int.h (__gconv_transliterate): Renamed from
gconv_transliterate. Remove two parameters.
Change prototypes of builtin functions according to __gconv_fct change.
* iconv/skeleton.c: Change type of fifth parameter. make sure it is
!= NULL only during error handling. Stop in this case after the
conversion.
* iconv/gconv_trans.c: Replace with real implementation for
__gconv_transliterate.
* iconv/gconv_open.c: Adjust for renaming of __gconv_transliterate.
* iconv/gconv.c: Change calls to downstream functions once again.
Use NULL for the fifth parameter instead of pointer to output buffer.
* libio/iofwide.c: Likewise.
* wcsmbs/btowc.c: Likewise.
* wcsmbs/mbrtowc.c: Likewise.
* wcsmbs/mbsnrtowcs.c: Likewise.
* wcsmbs/mbsrtowcs.c: Likewise.
* wcsmbs/wcrtomb.c: Likewise.
* wcsmbs/wcsnrtombs.c: Likewise.
* wcsmbs/wcsrtombs.c: Likewise.
* wcsmbs/wctob.c: Likewise.
* iconv/gconv_simple.c: Remove two parameters from error handling
function call.
* iconvdata/8bit-gap.c: Likewise.
* iconvdata/8bit-generic.c: Likewise.
* iconvdata/ansi_x3.110.c: Likewise.
* iconvdata/big5.c: Likewise.
* iconvdata/big5hkscs.c: Likewise.
* iconvdata/euc-cn.c: Likewise.
* iconvdata/euc-jp.c: Likewise.
* iconvdata/euc-kr.c: Likewise.
* iconvdata/euc-tw.c: Likewise.
* iconvdata/gbgbk.c: Likewise.
* iconvdata/gbk.c: Likewise.
* iconvdata/iso-2022-cn.c: Likewise.
* iconvdata/iso-2022-jp.c: Likewise.
* iconvdata/iso-2022-kr.c: Likewise.
* iconvdata/iso646.c: Likewise.
* iconvdata/iso8859-1.c: Likewise.
* iconvdata/iso_6937-2.c: Likewise.
* iconvdata/iso_6937.c: Likewise.
* iconvdata/johab.c: Likewise.
* iconvdata/sjis.c: Likewise.
* iconvdata/t.61.c: Likewise.
* iconvdata/uhc.c: Likewise.
* iconvdata/unicode.c: Likewise.
* iconvdata/utf-16.c: Likewise.
41 files changed, 254 insertions, 117 deletions
@@ -1,3 +1,55 @@ +2000-06-15 Ulrich Drepper <drepper@redhat.com> + + * iconv/gconv.h (__gconv_fct): Change type of fifth parameter to + unsigned char **. + (__gconv_init_fct): Remove two parameters. + * iconv/gconv_int.h (__gconv_transliterate): Renamed from + gconv_transliterate. Remove two parameters. + Change prototypes of builtin functions according to __gconv_fct change. + * iconv/skeleton.c: Change type of fifth parameter. make sure it is + != NULL only during error handling. Stop in this case after the + conversion. + * iconv/gconv_trans.c: Replace with real implementation for + __gconv_transliterate. + * iconv/gconv_open.c: Adjust for renaming of __gconv_transliterate. + * iconv/gconv.c: Change calls to downstream functions once again. + Use NULL for the fifth parameter instead of pointer to output buffer. + * libio/iofwide.c: Likewise. + * wcsmbs/btowc.c: Likewise. + * wcsmbs/mbrtowc.c: Likewise. + * wcsmbs/mbsnrtowcs.c: Likewise. + * wcsmbs/mbsrtowcs.c: Likewise. + * wcsmbs/wcrtomb.c: Likewise. + * wcsmbs/wcsnrtombs.c: Likewise. + * wcsmbs/wcsrtombs.c: Likewise. + * wcsmbs/wctob.c: Likewise. + * iconv/gconv_simple.c: Remove two parameters from error handling + function call. + * iconvdata/8bit-gap.c: Likewise. + * iconvdata/8bit-generic.c: Likewise. + * iconvdata/ansi_x3.110.c: Likewise. + * iconvdata/big5.c: Likewise. + * iconvdata/big5hkscs.c: Likewise. + * iconvdata/euc-cn.c: Likewise. + * iconvdata/euc-jp.c: Likewise. + * iconvdata/euc-kr.c: Likewise. + * iconvdata/euc-tw.c: Likewise. + * iconvdata/gbgbk.c: Likewise. + * iconvdata/gbk.c: Likewise. + * iconvdata/iso-2022-cn.c: Likewise. + * iconvdata/iso-2022-jp.c: Likewise. + * iconvdata/iso-2022-kr.c: Likewise. + * iconvdata/iso646.c: Likewise. + * iconvdata/iso8859-1.c: Likewise. + * iconvdata/iso_6937-2.c: Likewise. + * iconvdata/iso_6937.c: Likewise. + * iconvdata/johab.c: Likewise. + * iconvdata/sjis.c: Likewise. + * iconvdata/t.61.c: Likewise. + * iconvdata/uhc.c: Likewise. + * iconvdata/unicode.c: Likewise. + * iconvdata/utf-16.c: Likewise. + 2000-06-15 Greg McGary <greg@mcgary.org> * sysdeps/unix/make-syscalls.sh: Strip leading whitespace from lhs diff --git a/iconv/gconv.c b/iconv/gconv.c index 19f95622a2..0b7b917b6a 100644 --- a/iconv/gconv.c +++ b/iconv/gconv.c @@ -46,8 +46,8 @@ __gconv (__gconv_t cd, const unsigned char **inbuf, if (inbuf == NULL || *inbuf == NULL) /* We just flush. */ result = DL_CALL_FCT (cd->__steps->__fct, - (cd->__steps, cd->__data, NULL, NULL, - cd->__data[0].__outbuf, irreversible, 1, 0)); + (cd->__steps, cd->__data, NULL, NULL, NULL, + irreversible, 1, 0)); else { const unsigned char *last_start; @@ -59,7 +59,7 @@ __gconv (__gconv_t cd, const unsigned char **inbuf, last_start = *inbuf; result = DL_CALL_FCT (cd->__steps->__fct, (cd->__steps, cd->__data, inbuf, inbufend, - cd->__data[0].__outbuf, irreversible, 0, 0)); + NULL, irreversible, 0, 0)); } while (result == __GCONV_EMPTY_INPUT && last_start != *inbuf && *inbuf + cd->__steps->__min_needed_from <= inbufend); diff --git a/iconv/gconv.h b/iconv/gconv.h index 2bba133d0c..0164b62c8b 100644 --- a/iconv/gconv.h +++ b/iconv/gconv.h @@ -68,7 +68,7 @@ struct __gconv_trans_data; /* Type of a conversion function. */ typedef int (*__gconv_fct) (struct __gconv_step *, struct __gconv_step_data *, __const unsigned char **, __const unsigned char *, - unsigned char *, size_t *, int, int); + unsigned char **, size_t *, int, int); /* Constructor and destructor for local data for conversion step. */ typedef int (*__gconv_init_fct) (struct __gconv_step *); @@ -80,8 +80,8 @@ typedef int (*__gconv_trans_fct) (struct __gconv_step *step, struct __gconv_step_data *step_data, __const unsigned char *, __const unsigned char **, - __const unsigned char *, unsigned char *, - unsigned char **, unsigned char *, size_t *); + __const unsigned char *, unsigned char **, + size_t *); /* Function to call to provide transliteration module with context. */ typedef int (*__gconv_trans_context_fct) (struct __gconv_trans_data *data, diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 87287d7b26..34dff7d522 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -181,15 +181,13 @@ extern void __gconv_get_builtin_trans (const char *name, internal_function; /* Transliteration using the locale's data. */ -extern int gconv_transliterate (struct __gconv_step *step, - struct __gconv_step_data *step_data, - __const unsigned char *inbufstart, - __const unsigned char **inbufp, - __const unsigned char *inbufend, - unsigned char *outbufstart, - unsigned char **outbufp, - unsigned char *outbufend, - size_t *irreversible); +extern int __gconv_transliterate (struct __gconv_step *step, + struct __gconv_step_data *step_data, + __const unsigned char *inbufstart, + __const unsigned char **inbufp, + __const unsigned char *inbufend, + unsigned char **outbufstart, + size_t *irreversible); /* Builtin transformations. */ @@ -198,8 +196,9 @@ extern int gconv_transliterate (struct __gconv_step *step, extern int Name (struct __gconv_step *step, \ struct __gconv_step_data *data, \ const unsigned char **inbuf, \ - const unsigned char *inbufend, unsigned char *outbufstart, \ - size_t *irreversible, int do_flush, int consume_incomplete) + const unsigned char *inbufend, \ + unsigned char **outbufstart, size_t *irreversible, \ + int do_flush, int consume_incomplete) __BUILTIN_TRANS (__gconv_transform_ascii_internal); __BUILTIN_TRANS (__gconv_transform_internal_ascii); diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index 984ca9dc5d..14f1d5e0f9 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -86,7 +86,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, csnames = internal_trans_names; ncsnames = 1; - trans_fct = gconv_transliterate; + trans_fct = __gconv_transliterate; /* No context, init, or end function. */ } else if (strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0) diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 5033f3ef83..390574582f 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -801,7 +801,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, { \ result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ (step, step_data, *inptrp, &inptr, inend, \ - *outptrp, &outptr, outend, irreversible)); \ + &outptr, irreversible)); \ if (result != __GCONV_OK) \ break; \ } \ @@ -1190,7 +1190,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, { \ result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ (step, step_data, *inptrp, &inptr, inend, \ - *outptrp, &outptr, outend, irreversible)); \ + &outptr, irreversible)); \ if (result != __GCONV_OK) \ break; \ } \ @@ -1257,7 +1257,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, { \ result = DL_CALL_FCT (step_data->__trans.__trans_fct, \ (step, step_data, *inptrp, &inptr, inend, \ - *outptrp, &outptr, outend, irreversible)); \ + &outptr, irreversible)); \ if (result != __GCONV_OK) \ break; \ } \ diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c index 56c3ff6be6..829ff5f981 100644 --- a/iconv/gconv_trans.c +++ b/iconv/gconv_trans.c @@ -18,6 +18,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <dlfcn.h> #include <stdint.h> #include "gconv_int.h" @@ -25,26 +26,121 @@ int -gconv_transliterate (struct __gconv_step *step, - struct __gconv_step_data *step_data, - const unsigned char *inbufstart, - const unsigned char **inbufp, - const unsigned char *inbufend, - unsigned char *outbufstart, - unsigned char **outbufp, unsigned char *outbufend, - size_t *irreversible) +__gconv_transliterate (struct __gconv_step *step, + struct __gconv_step_data *step_data, + const unsigned char *inbufstart, + const unsigned char **inbufp, + const unsigned char *inbufend, + unsigned char **outbufstart, size_t *irreversible) { /* Find out about the locale's transliteration. */ - uint_fast32_t size = _NL_CURRENT_WORD (LC_CTYPE, - _NL_CTYPE_TRANSLIT_HASH_SIZE); - uint_fast32_t layers = _NL_CURRENT_WORD (LC_CTYPE, - _NL_CTYPE_TRANSLIT_HASH_LAYERS); + uint_fast32_t size; + uint_fast32_t layers; + uint32_t *from_idx; + uint32_t *from_tbl; + uint32_t *to_idx; + uint32_t *to_tbl; + uint32_t *winbuf; + uint32_t *winbufend; + uint_fast32_t low; + uint_fast32_t high; /* If there is no transliteration information in the locale don't do anything and return the error. */ + size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_HASH_SIZE); if (size == 0) return __GCONV_ILLEGAL_INPUT; - /* XXX For now we don't do anything. */ + /* Get the rest of the values. */ + layers = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_HASH_LAYERS); + from_idx = (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TRANSLIT_FROM_IDX); + from_tbl = (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TRANSLIT_FROM_TBL); + to_idx = (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TRANSLIT_TO_IDX); + to_tbl = (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TRANSLIT_TO_TBL); + + /* The input buffer. There are actually 4-byte values. */ + winbuf = (uint32_t *) *inbufp; + winbufend = (uint32_t *) inbufend; + + /* Test whether there is enough input. */ + if (winbuf + 1 > winbufend) + return (winbuf == winbufend + ? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT); + + /* The array starting at FROM_IDX contains indeces to the string table + in FROM_TBL. The indeces are sorted wrt to the strings. I.e., we + are doing binary search. */ + low = 0; + high = size; + while (low < high) + { + uint_fast32_t med = (low + high) / 2; + uint32_t idx; + int cnt; + + /* Compare the string at this index with the string at the current + position in the input buffer. */ + idx = from_idx[med]; + cnt = 0; + do + { + if (from_tbl[idx + cnt] != winbuf[cnt]) + /* Does not match. */ + break; + ++cnt; + } + while (from_tbl[idx + cnt] != L'\0' && winbuf + cnt < winbufend); + + if (cnt > 0 && from_tbl[idx + cnt] == L'\0') + { + /* Found a matching input sequence. Now try to convert the + possible replacements. */ + uint32_t idx2 = to_idx[med]; + + do + { + /* Determine length of replacement. */ + uint_fast32_t len = 0; + int res; + const unsigned char *toinptr; + + while (to_tbl[idx2 + len] != L'\0') + ++len; + + /* Try this input text. */ + toinptr = (const unsigned char *) &to_tbl[idx2]; + res = DL_CALL_FCT (step->__fct, + (step, step_data, &toinptr, + (const unsigned char *) &to_tbl[idx2 + len], + (unsigned char **) outbufstart, + irreversible, 0, 0)); + if (res != __GCONV_ILLEGAL_INPUT) + { + /* If the conversion succeeds we have to increment the + input buffer. */ + if (res == __GCONV_EMPTY_INPUT) + { + *inbufp += cnt * sizeof (uint32_t); + ++*irreversible; + } + + return res; + } + + /* Next replacement. */ + idx2 += len + 1; + } + while (to_tbl[idx2] != L'\0'); + + /* Nothing found, continue searching. */ + } + + if (winbuf + cnt >= winbufend || from_tbl[idx + cnt] < winbuf[cnt]) + low = idx; + else + high = idx; + } + + /* Haven't found a match. */ return __GCONV_ILLEGAL_INPUT; } diff --git a/iconv/skeleton.c b/iconv/skeleton.c index d64d7599b4..8dbebb81ac 100644 --- a/iconv/skeleton.c +++ b/iconv/skeleton.c @@ -271,7 +271,7 @@ gconv_init (struct __gconv_step *step) int FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, const unsigned char **inptrp, const unsigned char *inend, - unsigned char *outbufstart, size_t *irreversible, int do_flush, + unsigned char **outbufstart, size_t *irreversible, int do_flush, int consume_incomplete) { struct __gconv_step *next_step = step + 1; |
