diff options
Diffstat (limited to 'mbutil.c')
-rw-r--r-- | mbutil.c | 98 |
1 files changed, 52 insertions, 46 deletions
@@ -1,6 +1,6 @@ /* mbutil.c -- readline multibyte character utility functions */ -/* Copyright (C) 2001-2015 Free Software Foundation, Inc. +/* Copyright (C) 2001-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -76,9 +76,7 @@ int _rl_utf8locale = 0; #if defined(HANDLE_MULTIBYTE) static int -_rl_find_next_mbchar_internal (string, seed, count, find_non_zero) - char *string; - int seed, count, find_non_zero; +_rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_zero) { size_t tmp, len; mbstate_t ps; @@ -94,6 +92,11 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) return seed; point = seed + _rl_adjust_point (string, seed, &ps); + /* if _rl_adjust_point returns -1, the character or string is invalid. + treat as a byte. */ + if (point == seed - 1) /* invalid */ + return seed + 1; + /* if this is true, means that seed was not pointing to a byte indicating the beginning of a multibyte character. Correct the point and consume one char. */ @@ -105,7 +108,14 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) len = strlen (string + point); if (len == 0) break; - tmp = mbrtowc (&wc, string+point, len, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string+point, len, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* invalid bytes. assume a byte represents a character */ @@ -146,9 +156,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) } /*static*/ int -_rl_find_prev_mbchar_internal (string, seed, find_non_zero) - char *string; - int seed, find_non_zero; +_rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero) { mbstate_t ps; int prev, non_zero_prev, point, length; @@ -166,10 +174,17 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) prev = non_zero_prev = point = 0; while (point < seed) { - tmp = mbrtowc (&wc, string + point, length - point, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string + point, length - point, &ps); if (MB_INVALIDCH ((size_t)tmp)) { - /* in this case, bytes are invalid or shorted to compose + /* in this case, bytes are invalid or too short to compose multibyte char, so assume that the first byte represents a single character anyway. */ tmp = 1; @@ -206,13 +221,15 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) if an invalid multibyte sequence was encountered. It returns (size_t)(-2) if it couldn't parse a complete multibyte character. */ int -_rl_get_char_len (src, ps) - char *src; - mbstate_t *ps; +_rl_get_char_len (char *src, mbstate_t *ps) { - size_t tmp; + size_t tmp, l; + int mb_cur_max; - tmp = mbrlen((const char *)src, (size_t)strlen (src), ps); + /* Look at no more than MB_CUR_MAX characters */ + l = (size_t)strlen (src); + mb_cur_max = MB_CUR_MAX; + tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps); if (tmp == (size_t)(-2)) { /* shorted to compose multibyte char */ @@ -237,13 +254,7 @@ _rl_get_char_len (src, ps) /* compare the specified two characters. If the characters matched, return 1. Otherwise return 0. */ int -_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) - char *buf1; - int pos1; - mbstate_t *ps1; - char *buf2; - int pos2; - mbstate_t *ps2; +_rl_compare_chars (char *buf1, int pos1, mbstate_t *ps1, char *buf2, int pos2, mbstate_t *ps2) { int i, w1, w2; @@ -263,18 +274,16 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) /* adjust pointed byte and find mbstate of the point of string. adjusted point will be point <= adjusted_point, and returns differences of the byte(adjusted_point - point). - if point is invalied (point < 0 || more than string length), + if point is invalid (point < 0 || more than string length), it returns -1 */ int -_rl_adjust_point (string, point, ps) - char *string; - int point; - mbstate_t *ps; +_rl_adjust_point (char *string, int point, mbstate_t *ps) { - size_t tmp = 0; - int length; - int pos = 0; + size_t tmp; + int length, pos; + tmp = 0; + pos = 0; length = strlen(string); if (point < 0) return -1; @@ -283,10 +292,13 @@ _rl_adjust_point (string, point, ps) while (pos < point) { - tmp = mbrlen (string + pos, length - pos, ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[pos])) + tmp = 1; + else + tmp = mbrlen (string + pos, length - pos, ps); if (MB_INVALIDCH ((size_t)tmp)) { - /* in this case, bytes are invalid or shorted to compose + /* in this case, bytes are invalid or too short to compose multibyte char, so assume that the first byte represents a single character anyway. */ pos++; @@ -305,11 +317,7 @@ _rl_adjust_point (string, point, ps) } int -_rl_is_mbchar_matched (string, seed, end, mbchar, length) - char *string; - int seed, end; - char *mbchar; - int length; +_rl_is_mbchar_matched (char *string, int seed, int end, char *mbchar, int length) { int i; @@ -323,9 +331,7 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length) } wchar_t -_rl_char_value (buf, ind) - char *buf; - int ind; +_rl_char_value (char *buf, int ind) { size_t tmp; wchar_t wc; @@ -334,9 +340,13 @@ _rl_char_value (buf, ind) if (MB_LEN_MAX == 1 || rl_byte_oriented) return ((wchar_t) buf[ind]); + if (_rl_utf8locale && UTF8_SINGLEBYTE(buf[ind])) + return ((wchar_t) buf[ind]); l = strlen (buf); if (ind >= l - 1) return ((wchar_t) buf[ind]); + if (l < ind) /* Sanity check */ + l = strlen (buf+ind); memset (&ps, 0, sizeof (mbstate_t)); tmp = mbrtowc (&wc, buf + ind, l - ind, &ps); if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) @@ -350,9 +360,7 @@ _rl_char_value (buf, ind) characters. */ #undef _rl_find_next_mbchar int -_rl_find_next_mbchar (string, seed, count, flags) - char *string; - int seed, count, flags; +_rl_find_next_mbchar (char *string, int seed, int count, int flags) { #if defined (HANDLE_MULTIBYTE) return _rl_find_next_mbchar_internal (string, seed, count, flags); @@ -366,9 +374,7 @@ _rl_find_next_mbchar (string, seed, count, flags) we look for non-zero-width multibyte characters. */ #undef _rl_find_prev_mbchar int -_rl_find_prev_mbchar (string, seed, flags) - char *string; - int seed, flags; +_rl_find_prev_mbchar (char *string, int seed, int flags) { #if defined (HANDLE_MULTIBYTE) return _rl_find_prev_mbchar_internal (string, seed, flags); |