diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-06-17 07:39:18 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-06-17 07:39:18 +0000 |
commit | a8e4c924e8cdd2db10de2175f73c70ad43aa931b (patch) | |
tree | 9555863a7c6c9b6f3a98ed5b4bc33b60c7208163 /iconv/gconv_trans.c | |
parent | 1d96d74da7f6adccd82e4000efe38900b295467a (diff) | |
download | glibc-a8e4c924e8cdd2db10de2175f73c70ad43aa931b.zip glibc-a8e4c924e8cdd2db10de2175f73c70ad43aa931b.tar.gz glibc-a8e4c924e8cdd2db10de2175f73c70ad43aa931b.tar.bz2 |
Update.
2000-06-17 Ulrich Drepper <drepper@redhat.com>
* iconv/gconv_trans.c: Implement handling if translit_ignore.
* locale/langinfo.h: Add entries for translit_ignore information.
* locale/categories.def: Add entries for new LC_CTYPE elements.
* locale/C-ctype.c: Add initializers for new fields. Use NULL
pointer instead of "" where possible.
* locale/programs/ld-ctype.c: Write out translit_ignore information.
* intl/Depend: Add localedata.
* intl/tst-gettext.c: Call setlocale for LC_CTYPE.
* intl/tst-gettext.sh: Set LOCPATH to localedata build dir.
Diffstat (limited to 'iconv/gconv_trans.c')
-rw-r--r-- | iconv/gconv_trans.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c index 0bb5f00..269917b 100644 --- a/iconv/gconv_trans.c +++ b/iconv/gconv_trans.c @@ -123,6 +123,7 @@ __gconv_transliterate (struct __gconv_step *step, { *inbufp += cnt * sizeof (uint32_t); ++*irreversible; + res = __GCONV_OK; } return res; @@ -135,6 +136,11 @@ __gconv_transliterate (struct __gconv_step *step, /* Nothing found, continue searching. */ } + else if (cnt > 0) + /* This means that the input buffer contents matches a prefix of + an entry. Since we cannot match it unless we get more input, + we will tell the caller about it. */ + return __GCONV_INCOMPLETE_INPUT; if (winbuf + cnt >= winbufend || from_tbl[idx + cnt] < winbuf[cnt]) low = idx; @@ -142,8 +148,37 @@ __gconv_transliterate (struct __gconv_step *step, high = idx; } - /* One last chance: use the default replacement. */ no_rules: + /* Maybe the character is supposed to be ignored. */ + if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_IGNORE_LEN) != 0) + { + int n = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_IGNORE_LEN); + uint32_t *ranges = (uint32_t *) _NL_CURRENT (LC_CTYPE, + _NL_CTYPE_TRANSLIT_IGNORE); + uint32_t wc = *(uint32_t *) (*inbufp); + int i; + + /* Test whether there is enough input. */ + if (winbuf + 1 > winbufend) + return (winbuf == winbufend + ? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT); + + for (i = 0; i < n; ranges += 3, ++i) + if (ranges[0] <= wc && wc <= ranges[1] + && (wc - ranges[0]) % ranges[2] == 0) + { + /* Matches the range. Ignore it. */ + *inbufp += 4; + ++*irreversible; + return __GCONV_OK; + } + else if (wc < ranges[0]) + /* There cannot be any other matching range since they are + sorted. */ + break; + } + + /* One last chance: use the default replacement. */ default_missing = (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING); if (default_missing[0] != L'\0') @@ -153,6 +188,11 @@ __gconv_transliterate (struct __gconv_step *step, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN); int res; + /* Test whether there is enough input. */ + if (winbuf + 1 > winbufend) + return (winbuf == winbufend + ? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT); + res = DL_CALL_FCT (step->__fct, (step, step_data, &toinptr, (const unsigned char *) (default_missing + len), @@ -165,9 +205,10 @@ __gconv_transliterate (struct __gconv_step *step, input buffer. */ if (res == __GCONV_EMPTY_INPUT) { - /* We consuming one character. */ - ++*inbufp; + /* This worked but is not reversible. */ ++*irreversible; + *inbufp += 4; + res = __GCONV_OK; } return res; |