From 7a18043a968ec6d4b8c4c8cac059ad977d14e47c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Aug 2013 16:44:05 +0200 Subject: lineedit: improve Unicode handling (still buggy though) function old new delta unicode_strlen - 31 +31 read_line_input 3876 3879 +3 lineedit_read_key 255 246 -9 parse_and_put_prompt 785 755 -30 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/2 up/down: 34/-39) Total: -5 bytes Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 30 +++++++++++++++++++++++------- libbb/unicode.c | 5 +---- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 1313dd5d9..ecf3066b1 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1763,7 +1763,7 @@ static void ask_terminal(void) static void parse_and_put_prompt(const char *prmt_ptr) { cmdedit_prompt = prmt_ptr; - cmdedit_prmt_len = strlen(prmt_ptr); + cmdedit_prmt_len = unicode_strlen(prmt_ptr); put_prompt(); } #else @@ -1781,7 +1781,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) char c; char *pbuf; - cmdedit_prmt_len = 0; + /*cmdedit_prmt_len = 0; - already is */ cbuf[1] = '\0'; /* never changes */ @@ -1915,7 +1915,8 @@ static void parse_and_put_prompt(const char *prmt_ptr) } case '[': case ']': if (c == flg_not_length) { - flg_not_length = (flg_not_length == '[' ? ']' : '['); + /* Toggle '['/']' hex 5b/5d */ + flg_not_length ^= 6; continue; } break; @@ -1925,8 +1926,13 @@ static void parse_and_put_prompt(const char *prmt_ptr) cbuf[0] = c; cur_prmt_len = strlen(pbuf); prmt_len += cur_prmt_len; - if (flg_not_length != ']') + if (flg_not_length != ']') { +#if 0 /*ENABLE_UNICODE_SUPPORT - won't work, pbuf is one BYTE string here. FIXME */ + cmdedit_prmt_len += unicode_strlen(pbuf); +#else cmdedit_prmt_len += cur_prmt_len; +#endif + } prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); free(free_me); } /* while */ @@ -1996,7 +2002,15 @@ static int lineedit_read_key(char *read_key_buffer, int timeout) S.sent_ESC_br6n = 0; if (cursor == 0) { /* otherwise it may be bogus */ int col = ((ic >> 32) & 0x7fff) - 1; - if (col > cmdedit_prmt_len) { + /* + * Is col > cmdedit_prmt_len? + * If yes (terminal says cursor is farther to the right + * of where we think it should be), + * the prompt wasn't printed starting at col 1, + * there was additional text before it. + */ + if ((int)(col - cmdedit_prmt_len) > 0) { + /* Fix our understanding of current x position */ cmdedit_x += (col - cmdedit_prmt_len); while (cmdedit_x >= cmdedit_termw) { cmdedit_x -= cmdedit_termw; @@ -2087,6 +2101,7 @@ static int32_t reverse_i_search(void) char read_key_buffer[KEYCODE_BUFFER_SIZE]; const char *matched_history_line; const char *saved_prompt; + unsigned saved_prmt_len; int32_t ic; matched_history_line = NULL; @@ -2095,6 +2110,7 @@ static int32_t reverse_i_search(void) /* Save and replace the prompt */ saved_prompt = cmdedit_prompt; + saved_prmt_len = cmdedit_prmt_len; goto set_prompt; while (1) { @@ -2170,7 +2186,7 @@ static int32_t reverse_i_search(void) free((char*)cmdedit_prompt); set_prompt: cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf); - cmdedit_prmt_len = strlen(cmdedit_prompt); + cmdedit_prmt_len = unicode_strlen(cmdedit_prompt); goto do_redraw; } } @@ -2192,7 +2208,7 @@ static int32_t reverse_i_search(void) free((char*)cmdedit_prompt); cmdedit_prompt = saved_prompt; - cmdedit_prmt_len = strlen(cmdedit_prompt); + cmdedit_prmt_len = saved_prmt_len; redraw(cmdedit_y, command_len - cursor); return ic; diff --git a/libbb/unicode.c b/libbb/unicode.c index 2e5dd5adc..9c4da50d3 100644 --- a/libbb/unicode.c +++ b/libbb/unicode.c @@ -43,8 +43,7 @@ void FAST_FUNC reinit_unicode(const char *LANG) setlocale(LC_CTYPE, LANG ? LANG : ""); /* In unicode, this is a one character string */ -// can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused - width = mbstowcs(NULL, unicode_0x394, INT_MAX); + width = unicode_strlen(unicode_0x394); unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF); } @@ -986,7 +985,6 @@ int FAST_FUNC unicode_bidi_is_neutral_wchar(wint_t wc) /* The rest is mostly same for libc and for "homegrown" support */ -#if 0 // UNUSED size_t FAST_FUNC unicode_strlen(const char *string) { size_t width = mbstowcs(NULL, string, INT_MAX); @@ -994,7 +992,6 @@ size_t FAST_FUNC unicode_strlen(const char *string) return strlen(string); return width; } -#endif size_t FAST_FUNC unicode_strwidth(const char *string) { -- cgit v1.2.3