From 781c7a7a5f88dd7c42cca3b994be15d41f177d33 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Sun, 9 Jun 2019 17:36:29 +0200 Subject: [PATCH] chars: create a dedicated function for getting the length of a character Instead of calling in twenty places parse_mbchar(pointer, NULL, NULL), use a simpler and faster char_length(pointer). This saves pushing two unneeded parameters onto the stack, avoids two needless ifs, and elides an intermediate variable. Its main purpose will follow in a later commit: to speed up searching. --- src/chars.c | 16 ++++++++++++++-- src/cut.c | 4 ++-- src/prompt.c | 2 +- src/proto.h | 1 + src/rcfile.c | 4 ++-- src/search.c | 6 +++--- src/text.c | 18 +++++++++--------- src/winio.c | 4 ++-- 8 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/chars.c b/src/chars.c index cf97df6c..2f8ae286 100644 --- a/src/chars.c +++ b/src/chars.c @@ -280,6 +280,18 @@ char *make_mbchar(long chr, int *chr_mb_len) return chr_mb; } +/* Return the length (in bytes) of the character located at *pointer. */ +int char_length(const char *pointer) +{ + /* If possibly a multibyte character, get its length; otherwise, it's 1. */ + if ((signed char)*pointer < 0) { + int length = mblen(pointer, MAXCHARLEN); + + return (length > 0 ? length : 1); + } else + return 1; +} + /* Parse a multibyte character from buf. Return the number of bytes * used. If chr isn't NULL, store the multibyte character in it. If * col isn't NULL, add the character's width (in columns) to it. */ @@ -355,7 +367,7 @@ size_t move_mbleft(const char *buf, size_t pos) /* Move forward again until we reach the original character, * so we know the length of its preceding character. */ while (before < pos) { - charlen = parse_mbchar(buf + before, NULL, NULL); + charlen = char_length(buf + before); before += charlen; } @@ -369,7 +381,7 @@ size_t move_mbleft(const char *buf, size_t pos) * after the one at pos. */ size_t move_mbright(const char *buf, size_t pos) { - return pos + parse_mbchar(buf + pos, NULL, NULL); + return pos + char_length(buf + pos); } /* This function is equivalent to strcasecmp() for multibyte strings. */ diff --git a/src/cut.c b/src/cut.c index 5be5cad7..a8f21415 100644 --- a/src/cut.c +++ b/src/cut.c @@ -35,8 +35,8 @@ void do_deletion(undo_type action) /* When in the middle of a line, delete the current character. */ if (openfile->current->data[openfile->current_x] != '\0') { - int charlen = parse_mbchar(openfile->current->data + - openfile->current_x, NULL, NULL); + int charlen = char_length(openfile->current->data + + openfile->current_x); size_t line_len = strlen(openfile->current->data + openfile->current_x); #ifndef NANO_TINY diff --git a/src/prompt.c b/src/prompt.c index 8a2d6225..8259ad2c 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -253,7 +253,7 @@ void do_statusbar_right(void) void do_statusbar_delete(void) { if (answer[typing_x] != '\0') { - int charlen = parse_mbchar(answer + typing_x, NULL, NULL); + int charlen = char_length(answer + typing_x); charmove(answer + typing_x, answer + typing_x + charlen, strlen(answer) - typing_x - charlen + 1); diff --git a/src/proto.h b/src/proto.h index 51ca63e4..95c272ac 100644 --- a/src/proto.h +++ b/src/proto.h @@ -213,6 +213,7 @@ char control_mbrep(const char *c, bool isdata); int length_of_char(const char *c, int *width); int mbwidth(const char *c); char *make_mbchar(long chr, int *chr_mb_len); +int char_length(const char *pointer); int parse_mbchar(const char *buf, char *chr, size_t *col); size_t move_mbleft(const char *buf, size_t pos); size_t move_mbright(const char *buf, size_t pos); diff --git a/src/rcfile.c b/src/rcfile.c index 19cb53b2..b5225168 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -1226,8 +1226,8 @@ void parse_rcfile(FILE *rcstream, bool syntax_only, bool headers_only) free(option); } else { whitespace = option; - whitelen[0] = parse_mbchar(whitespace, NULL, NULL); - whitelen[1] = parse_mbchar(whitespace + whitelen[0], NULL, NULL); + whitelen[0] = char_length(whitespace); + whitelen[1] = char_length(whitespace + whitelen[0]); } } else #endif diff --git a/src/search.c b/src/search.c index 4b2e2a16..1dd48aca 100644 --- a/src/search.c +++ b/src/search.c @@ -931,7 +931,7 @@ void do_find_bracket(void) /* Find the halfway point in matchbrackets, where the closing ones start. */ for (size_t i = 0; i < charcount; i++) - halfway += parse_mbchar(matchbrackets + halfway, NULL, NULL); + halfway += char_length(matchbrackets + halfway); /* When on a closing bracket, we have to search backwards for a matching * opening bracket; otherwise, forward for a matching closing bracket. */ @@ -948,8 +948,8 @@ void do_find_bracket(void) wanted_ch += move_mbright(wanted_ch, 0); } - ch_len = parse_mbchar(ch, NULL, NULL); - wanted_ch_len = parse_mbchar(wanted_ch, NULL, NULL); + ch_len = char_length(ch); + wanted_ch_len = char_length(wanted_ch); /* Copy the two complementary brackets into a single string. */ strncpy(bracket_pair, ch, ch_len); diff --git a/src/text.c b/src/text.c index a6b7e1cb..1c4ea5b7 100644 --- a/src/text.c +++ b/src/text.c @@ -1548,7 +1548,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl) else if (lastblank > 0) return lastblank; - charlen = parse_mbchar(line, NULL, NULL); + charlen = char_length(line); line += charlen; index += charlen; } @@ -1558,13 +1558,13 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl) /* Move the pointer back to the last blank, and then step beyond it. */ line = line - index + lastblank; - charlen = parse_mbchar(line, NULL, NULL); + charlen = char_length(line); line += charlen; /* Skip any consecutive blanks after the last blank. */ while (*line != '\0' && is_blank_mbchar(line)) { lastblank += charlen; - charlen = parse_mbchar(line, NULL, NULL); + charlen = char_length(line); line += charlen; } @@ -1599,7 +1599,7 @@ size_t indent_length(const char *line) /* Copy a character from one place to another. */ void copy_character(char **from, char **to) { - int charlen = parse_mbchar(*from, NULL, NULL); + int charlen = char_length(*from); if (*from == *to) { *from += charlen; @@ -1624,11 +1624,11 @@ void squeeze(linestruct *line, size_t skip) * pass over all blanks after these; 3) leave anything else unchanged. */ while (*from != '\0') { if (is_blank_mbchar(from)) { - from += parse_mbchar(from, NULL, NULL); + from += char_length(from); *(to++) = ' '; while (*from != '\0' && is_blank_mbchar(from)) - from += parse_mbchar(from, NULL, NULL); + from += char_length(from); } else if (mbstrchr(punct, from) != NULL) { copy_character(&from, &to); @@ -1636,16 +1636,16 @@ void squeeze(linestruct *line, size_t skip) copy_character(&from, &to); if (*from != '\0' && is_blank_mbchar(from)) { - from += parse_mbchar(from, NULL, NULL); + from += char_length(from); *(to++) = ' '; } if (*from != '\0' && is_blank_mbchar(from)) { - from += parse_mbchar(from, NULL, NULL); + from += char_length(from); *(to++) = ' '; } while (*from != '\0' && is_blank_mbchar(from)) - from += parse_mbchar(from, NULL, NULL); + from += char_length(from); } else copy_character(&from, &to); } diff --git a/src/winio.c b/src/winio.c index cce20f33..80a8ae38 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1903,7 +1903,7 @@ char *display_string(const char *buf, size_t column, size_t span, if (start_col < column) { converted[index++] = control_mbrep(buf, isdata); column++; - buf += parse_mbchar(buf, NULL, NULL); + buf += char_length(buf); } } #ifdef ENABLE_UTF8 @@ -1916,7 +1916,7 @@ char *display_string(const char *buf, size_t column, size_t span, /* Display the right half of a two-column character as ']'. */ converted[index++] = ']'; column++; - buf += parse_mbchar(buf, NULL, NULL); + buf += char_length(buf); } #endif }