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 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. */

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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
}