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.
master
Benno Schulenberg 2019-06-09 17:36:29 +02:00
parent aa205f58ca
commit 781c7a7a5f
8 changed files with 34 additions and 21 deletions

View File

@ -280,6 +280,18 @@ char *make_mbchar(long chr, int *chr_mb_len)
return chr_mb; 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 /* Parse a multibyte character from buf. Return the number of bytes
* used. If chr isn't NULL, store the multibyte character in it. If * 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. */ * 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, /* Move forward again until we reach the original character,
* so we know the length of its preceding character. */ * so we know the length of its preceding character. */
while (before < pos) { while (before < pos) {
charlen = parse_mbchar(buf + before, NULL, NULL); charlen = char_length(buf + before);
before += charlen; before += charlen;
} }
@ -369,7 +381,7 @@ size_t move_mbleft(const char *buf, size_t pos)
* after the one at pos. */ * after the one at pos. */
size_t move_mbright(const char *buf, size_t 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. */ /* This function is equivalent to strcasecmp() for multibyte strings. */

View File

@ -35,8 +35,8 @@ void do_deletion(undo_type action)
/* When in the middle of a line, delete the current character. */ /* When in the middle of a line, delete the current character. */
if (openfile->current->data[openfile->current_x] != '\0') { if (openfile->current->data[openfile->current_x] != '\0') {
int charlen = parse_mbchar(openfile->current->data + int charlen = char_length(openfile->current->data +
openfile->current_x, NULL, NULL); openfile->current_x);
size_t line_len = strlen(openfile->current->data + size_t line_len = strlen(openfile->current->data +
openfile->current_x); openfile->current_x);
#ifndef NANO_TINY #ifndef NANO_TINY

View File

@ -253,7 +253,7 @@ void do_statusbar_right(void)
void do_statusbar_delete(void) void do_statusbar_delete(void)
{ {
if (answer[typing_x] != '\0') { 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, charmove(answer + typing_x, answer + typing_x + charlen,
strlen(answer) - typing_x - charlen + 1); strlen(answer) - typing_x - charlen + 1);

View File

@ -213,6 +213,7 @@ char control_mbrep(const char *c, bool isdata);
int length_of_char(const char *c, int *width); int length_of_char(const char *c, int *width);
int mbwidth(const char *c); int mbwidth(const char *c);
char *make_mbchar(long chr, int *chr_mb_len); 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); int parse_mbchar(const char *buf, char *chr, size_t *col);
size_t move_mbleft(const char *buf, size_t pos); size_t move_mbleft(const char *buf, size_t pos);
size_t move_mbright(const char *buf, size_t pos); size_t move_mbright(const char *buf, size_t pos);

View File

@ -1226,8 +1226,8 @@ void parse_rcfile(FILE *rcstream, bool syntax_only, bool headers_only)
free(option); free(option);
} else { } else {
whitespace = option; whitespace = option;
whitelen[0] = parse_mbchar(whitespace, NULL, NULL); whitelen[0] = char_length(whitespace);
whitelen[1] = parse_mbchar(whitespace + whitelen[0], NULL, NULL); whitelen[1] = char_length(whitespace + whitelen[0]);
} }
} else } else
#endif #endif

View File

@ -931,7 +931,7 @@ void do_find_bracket(void)
/* Find the halfway point in matchbrackets, where the closing ones start. */ /* Find the halfway point in matchbrackets, where the closing ones start. */
for (size_t i = 0; i < charcount; i++) 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 /* When on a closing bracket, we have to search backwards for a matching
* opening bracket; otherwise, forward for a matching closing bracket. */ * 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); wanted_ch += move_mbright(wanted_ch, 0);
} }
ch_len = parse_mbchar(ch, NULL, NULL); ch_len = char_length(ch);
wanted_ch_len = parse_mbchar(wanted_ch, NULL, NULL); wanted_ch_len = char_length(wanted_ch);
/* Copy the two complementary brackets into a single string. */ /* Copy the two complementary brackets into a single string. */
strncpy(bracket_pair, ch, ch_len); strncpy(bracket_pair, ch, ch_len);

View File

@ -1548,7 +1548,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl)
else if (lastblank > 0) else if (lastblank > 0)
return lastblank; return lastblank;
charlen = parse_mbchar(line, NULL, NULL); charlen = char_length(line);
line += charlen; line += charlen;
index += 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. */ /* Move the pointer back to the last blank, and then step beyond it. */
line = line - index + lastblank; line = line - index + lastblank;
charlen = parse_mbchar(line, NULL, NULL); charlen = char_length(line);
line += charlen; line += charlen;
/* Skip any consecutive blanks after the last blank. */ /* Skip any consecutive blanks after the last blank. */
while (*line != '\0' && is_blank_mbchar(line)) { while (*line != '\0' && is_blank_mbchar(line)) {
lastblank += charlen; lastblank += charlen;
charlen = parse_mbchar(line, NULL, NULL); charlen = char_length(line);
line += charlen; line += charlen;
} }
@ -1599,7 +1599,7 @@ size_t indent_length(const char *line)
/* Copy a character from one place to another. */ /* Copy a character from one place to another. */
void copy_character(char **from, char **to) void copy_character(char **from, char **to)
{ {
int charlen = parse_mbchar(*from, NULL, NULL); int charlen = char_length(*from);
if (*from == *to) { if (*from == *to) {
*from += charlen; *from += charlen;
@ -1624,11 +1624,11 @@ void squeeze(linestruct *line, size_t skip)
* pass over all blanks after these; 3) leave anything else unchanged. */ * pass over all blanks after these; 3) leave anything else unchanged. */
while (*from != '\0') { while (*from != '\0') {
if (is_blank_mbchar(from)) { if (is_blank_mbchar(from)) {
from += parse_mbchar(from, NULL, NULL); from += char_length(from);
*(to++) = ' '; *(to++) = ' ';
while (*from != '\0' && is_blank_mbchar(from)) while (*from != '\0' && is_blank_mbchar(from))
from += parse_mbchar(from, NULL, NULL); from += char_length(from);
} else if (mbstrchr(punct, from) != NULL) { } else if (mbstrchr(punct, from) != NULL) {
copy_character(&from, &to); copy_character(&from, &to);
@ -1636,16 +1636,16 @@ void squeeze(linestruct *line, size_t skip)
copy_character(&from, &to); copy_character(&from, &to);
if (*from != '\0' && is_blank_mbchar(from)) { if (*from != '\0' && is_blank_mbchar(from)) {
from += parse_mbchar(from, NULL, NULL); from += char_length(from);
*(to++) = ' '; *(to++) = ' ';
} }
if (*from != '\0' && is_blank_mbchar(from)) { if (*from != '\0' && is_blank_mbchar(from)) {
from += parse_mbchar(from, NULL, NULL); from += char_length(from);
*(to++) = ' '; *(to++) = ' ';
} }
while (*from != '\0' && is_blank_mbchar(from)) while (*from != '\0' && is_blank_mbchar(from))
from += parse_mbchar(from, NULL, NULL); from += char_length(from);
} else } else
copy_character(&from, &to); copy_character(&from, &to);
} }

View File

@ -1903,7 +1903,7 @@ char *display_string(const char *buf, size_t column, size_t span,
if (start_col < column) { if (start_col < column) {
converted[index++] = control_mbrep(buf, isdata); converted[index++] = control_mbrep(buf, isdata);
column++; column++;
buf += parse_mbchar(buf, NULL, NULL); buf += char_length(buf);
} }
} }
#ifdef ENABLE_UTF8 #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 ']'. */ /* Display the right half of a two-column character as ']'. */
converted[index++] = ']'; converted[index++] = ']';
column++; column++;
buf += parse_mbchar(buf, NULL, NULL); buf += char_length(buf);
} }
#endif #endif
} }